Eleno
Eleno

Reputation: 3016

Porting an OOP application without inheritance to Erlang

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

Answers (1)

tkowal
tkowal

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

Related Questions