Bercovici Adrian
Bercovici Adrian

Reputation: 9360

How to load multiple modules implementing the same behaviour

I do not understand how is one supposed to use multiple modules that each implement the same behaviour since i get this error at compile time:

Function is already imported from

In my case i have two modules implementing gen_event behaviour and i am trying to import them in a third module. I get the error message whenever i am trying to compile this code:

-module(mgr).
-import(h1,[init/1]).   // implements gen_event
-import(h2,[init/1]).   // implements gen_event

Upvotes: 2

Views: 654

Answers (1)

Pascal
Pascal

Reputation: 14042

You can't do that. Import is a simple trick to avoid to write the complete "definition" of a function. It does nothing but just says to the compiler : when you see init(P) in this module, replace with h1:init(P).

Thus it is not possible to import several function with the same name/arity.

For short names, I do not see any benefit to use import.

If you are using module:function with long names, and you want to shorten the lines in the code, it is possible to use macros instead, and there are no limitation (but also few chance that the function name are the same :o):

-define(Func1(Var1,...,VarN), module1:func(Var1,...,VarN)). 
-define(Func2(Var1,...,VarN), module2:func(Var1,...,VarN)). 
...
?Func1(A1,...,AN);
...
?Func2(B1,...,BN);

Edit

The next example illustrates how it works, first I create the module mod1 as follow:

-module (mod1).

-export ([test/1]).

test(P) ->
    case P of 
        1 -> ok;
        2 -> mod2:test()
    end.

and I test it in the shell:

1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.

mod2 is created as:

-module (mod2).

-export ([test/0]).

test() ->
    io:format("now it works~n").

continue in the shell:

4> c(mod2).
{ok,mod2}
5> mod1:test(1).                                   
ok
6> mod1:test(2).                                   
now it works
ok
7> 

As you can see, it is not necessary to modify mod1, but only to create and compile mod2 (note that it would be the same if mod2 already exists but the function test/0 is not exported).

If you want to verify that your code is not using undefined function, you can use external tools. As I am using rebar3 to manage my projects, I use the command rebar3 xref to perform this check. Note that calling an undefined function is a simple warning, it is meaningful in the context of application upgrading. This verification is not bullet proof: it is done at build time, this does not guarantee that the modules yo need will be present, with the right version on a production system: it opens a lot more interesting questions about versioning, code loading...

Upvotes: 3

Related Questions