How to dynamically call a module in Erlang?

Suppose I have two modules a.erl and b.erl . Both modules contain the same functions (in Java, I would say that "both classes implement the same interface"). In the module "c.erl" I want to have a function that will return the module "a" or "b" (depending on the parameter)

Here is what I want in c.erl module

-module(c) get_handler(Id) -> % if Id == "a" return a % if Id == "b" return b test() -> get_handler("a"):some_function1("here were go for a"), get_handler("a"):some_function2("aaaa"), get_handler("b"):some_function1("here we go for b") 

How can I do this job? I am relatively new to Erlang and don't know how to do this. In Java, this would be very obvious because you are simply returning a new instance of the class.

+6
source share
2 answers

Just get_handler/1 return the module name as an atom, and then use it to call the function you get_handler/1 :

 (get_handler("a")):some_function2("aaaa"), (get_handler("b")):some_function1("here we go for b"). 

Note that in this case you need parentheses around the call to get_handler/1 .

A simple get_handler/1 option for modules a and b could be:

 get_handler("a") -> a; get_handler("b") -> b. 
+7
source

If you have an atom in a variable, you can use it as the name of the module.

So you can define c:get_handler/1 as follows:

 get_handler("a") -> a; get_handler("b") -> b. 

Your c:test/0 looks fine, except you need extra brackets, for example:

 test() -> (get_handler("a")):some_function1("here were go for a"), (get_handler("a")):some_function2("aaaa"), (get_handler("b")):some_function1("here we go for b"). 

Then in modules a and b just define some_function1/1 and some_function/2 , for example:

 some_function1(Str) -> io:format("module ~s function some_function1 string ~s~n", [?MODULE, Str]). some_function2(Str) -> io:format("module ~s function some_function2 string ~s~n", [?MODULE, Str]). 

Edit: You should also determine the behavior if you are going to do such BTW things, which would mean that you would declare something like this in modules a and b

 -behaviour(some_behaviour). 

Then create some_behaviour module something like this:

 -module(some_behaviour). -callback some_function1 (String :: string()) -> ok . -callback some_function2 (String :: string()) -> ok . 

This means that any module, such as a and b , declaring that they support the behavior of some_behaviour , must define these functions, and the compiler will say if they do not. Parameter types and return value are also defined here for static analysis, etc.

+5
source

All Articles