Reputation: 3016
I have an application that extracts information from different data sources. Since the extraction process is the same, except some steps, I have abstracted such different steps in corresponding classes, and I instantiate and pass each object to a generic search procedure. I suppose that -- in Erlang -- I would use a record of functions instead of an object, right?
In case my description is not clear, here is some very simplified pseudo-code:
class Query1:
def query_a(data):
...
def query_b(data):
...
class Query2:
def query_a(data):
...
def query_b(data):
...
def extract_info(data,query):
# Calls the methods `query_a` and `query_b` of `query`.
# `query` can be either a `Query1` object or a `Query2` object.
Upvotes: 1
Views: 93
Reputation: 9289
You have couple of options:
You can pass both query_a
and query_b
as anonymous functions.
extract_info(Data, QueryA, QueryB) ->
A = QueryA(Data),
B = QueryB(Data),
...
extract_info(Data, fun({A, _B} -> A end, fun {_A, B} -> B end).
If the query logic is complex, you can define modules query_a
and query_b
and pass single atom to extract info:
-module(query1).
-compile([export_all]).
query_a({A, _B}) ->
A.
query_b({_A, B}) ->
B.
query2
module would be analogus.
-module(other_module).
...
extract_info(Data, Query) ->
A = Query:query_a(Data),
B = Query:query_b(Data)
...
extract_info(Data, query1).
If the query logic depends only on data source, you can use function clauses that pattern match on different types. Lets say, that your data are tuples. Type one is something like this {A, B}
, and second type is something like this {{data1, A}, {data2, B}}
query_a({A, _B}) ->
A;
query_a({{data1, A}, {data2, _B}}) ->
A.
query_b({_A, B}) ->
B;
query_b({{data1, _A}, {data2, B}}) ->
B.
extract_info(Data) ->
A = query_a(Data),
B = query_b(Data).
If the data sources are similar, you can always tag the tuples with single atom like: {data1, A, B}
and {data2, A, B}
. The last option is the most idiomatic if the query logic depends only on data type. For different queries, you have to use one of the previous ones.
Upvotes: 3