Erlang/OTP Forums

Author Message

<  Erlang  ~  How to have a dynamic reference to a module?

jacek99
Posted: Thu Jun 04, 2009 1:54 pm Reply with quote
User Joined: 26 May 2009 Posts: 27 Location: Montreal, Canada
Let's say I have two implementations of some logic in 2 separate modules:

module1
module2

Depending on a config file I would like to use one of the two.

In a lang like Java, they would be objects that implement the same interface, I would instantiate it to the reference of the interface type and just pass it around.

But I am not sure at all how to do the equivalent in Erlang/OTP.

I presume both modules should implement the same behavior?
But how do I take it from there...what sort of language construct would you need to assign an instance of a behavior to a module that implements it and pass that around for spawned processes?
View user's profile Send private message
seanmc
Posted: Thu Jun 04, 2009 2:17 pm Reply with quote
User Joined: 03 Aug 2007 Posts: 10
Hi Jacek,

This is really easy in Erlang. If you read your config file and assign the module name to a variable (as an atom):

Mod = read_config_file().

Then you can call its functions as normal, using the variable module name:

Mod:function1(),
Mod:function2().

Of course this assumes that any module you specify is loaded and that the functions called have the same interface.
The function names can also be variables, try in the shell:

(test@linux)1> M = io.
io
(test@linux)2> F = format.
format
(test@linux)3> M:F("~nHello~n~n").

Hello

ok
(test@linux)4>
(test@linux)4>


//Sean.
View user's profile Send private message
jacek99
Posted: Thu Jun 04, 2009 5:18 pm Reply with quote
User Joined: 26 May 2009 Posts: 27 Location: Montreal, Canada
Ah, very cool.

So, the whole concept of behaviors in Erlang is really just sort of a compiler hint more than anything else?

It's not actually used at runtime when invoking methods on a particular module?
View user's profile Send private message
jacek99
Posted: Thu Jun 04, 2009 8:01 pm Reply with quote
User Joined: 26 May 2009 Posts: 27 Location: Montreal, Canada
They way I did it is as a macro in an .hrl file:

-define(MODULE,module1)

Then just refer to it in the code

?MODULE:start()
?MODULE:stop()
etc.

if we want to test a different implementation, I just change the .hrl to point to a different module atom.

is this a proper Erlang-ish solution to the problem?

P.S. I wanted to write a Java-style factory first, but some instinct told me it's just not the right way to do it in Erlang.
Cool
View user's profile Send private message
uwiger
Posted: Fri Jun 05, 2009 11:28 am Reply with quote
User Joined: 03 Jul 2006 Posts: 604 Location: Sweden
jacek99 wrote:
They way I did it is as a macro in an .hrl file:

-define(MODULE,module1)

Then just refer to it in the code

?MODULE:start()
?MODULE:stop()
etc.

if we want to test a different implementation, I just change the .hrl to point to a different module atom.

is this a proper Erlang-ish solution to the problem?


It is a fairly common way to do it, except that the macro ?MODULE is automatically defined as the current module. You should pick another name.

Sometimes, it can be appropriate to use the -import(Mod, Fns) directive (I know others would say that it's never appropriate.) The modules dict, orddict, and gb_dict, for example, have the same interface, but different performance characteristics. During early development, orddict might be best, since it is easy on the eyes when appearing in crash reports, etc. If it becomes obvious that it doesn't scale well enough for the problem, one would like to change to e.g. dict in one place only.

BR,
Ulf W
View user's profile Send private message Visit poster's website
uwiger
Posted: Fri Jun 05, 2009 11:41 am Reply with quote
User Joined: 03 Jul 2006 Posts: 604 Location: Sweden
jacek99 wrote:
Ah, very cool.

So, the whole concept of behaviors in Erlang is really just sort of a compiler hint more than anything else?

It's not actually used at runtime when invoking methods on a particular module?


That is only part of it. The -behaviour attribute indicates to the programmer as well as the linter what callback functions to expect in the module.

Mostly, though, a behaviour will include both a "specification" for the callbacks expected in the user-defined module, and the runtime framework for instantiating and calling the user-defined module.

That is, gen_server.erl is the module that defines the behaviour gen_server. It is called on by the linter at compile-time to list the expected callback functions, but it also has an API of its own, for the generic parts of the behaviour. In order to use a gen_server callback, you obviously have to call on the support functions in gen_server to create the framework in which the callback makes sense.
View user's profile Send private message Visit poster's website
jacek99
Posted: Fri Jun 05, 2009 1:40 pm Reply with quote
User Joined: 26 May 2009 Posts: 27 Location: Montreal, Canada
uwiger wrote:

It is a fairly common way to do it, except that the macro ?MODULE is automatically defined as the current module. You should pick another name.


Sorry, my mistake. That's just the name I used in the example, in the code we used a different name obviously. Thanks for validating my solution was the proper approach, much appreciated.
View user's profile Send private message
jacek99
Posted: Fri Jun 05, 2009 1:44 pm Reply with quote
User Joined: 26 May 2009 Posts: 27 Location: Montreal, Canada
Sorry, my mistake about MODULE. That's just the name I used in the example, in the code we used a different name obviously. Thanks for validating my solution was the proper approach, much appreciated.
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum