[erlang-questions] parameterized modules and OO

Torbjorn Tornkvist <>
Wed May 30 16:01:17 CEST 2007


Richard Carlsson wrote:
> Torbjorn Tornkvist wrote:
>> So I was thinking, would it be possible for a parameterized module
>> to modify its own module attributes ?
>> [...]
>> So would this be possible to add without too much hassle ?
>>
>> Cheers, Tobbe
>> (NB: I'm not saying this is good or bad, I'm not even proposing
>> this, I'm just curious to hear if it would be easy/hard/impossible to 
>> add this functionality.)
> 
> - The current runtime system does not support runtime changes to the
> attributes (the module_info stuff) of a module.

So how easy/hard/impossible would it be to add this functionality ?

> 
> - The attributes are per-loaded-module ("class members" in OO
> terminology), and what you probably want is a table of attributes per 
> module instance. That table should thus be created when you call 'new'.
> There are at least two possible ways of hiding the table creation:
> 
>    1: Specify the abstract module with N parameters, the last one being
>       the per-instance table, and insert a hand-written function new/M
>       where M=N-1, which calls the autogenerated new/N with a freshly
>       created table.
> 
>    2: Separate the actual abstract module implementation and its
>       interface: give the abstract module some other name, and let the
>       interface module have a new/M function which calls the new/N
>       function of the abstract module with the extra parameters.
> 
>    /Richard
> 

Yes, I did it like this:

%%---
-module(mstring).
-export([new/1]).
new(String) ->
     M = mstring__:new({node(),now()}, String),
     M:init_(),
     M.

%%---
-module(mstring__, [Id,InitString]).
-export([init_/0, len/0, append/1]).
-record(string, {obj = "", len = 0}).
init_()  ->
     Obj = #string{obj = InitString, len = length(InitString)},
     put_(Obj),
     THIS.
get_() ->
     mobject_store:lookup(THIS).
put_(NewObject) ->
     mobject_store:insert(THIS, NewObject).
len() ->
     #string{len = Len} = get_(),
     Len.
append(Str) ->
     #string{obj = Obj} = X = get_(),
     Res = Obj ++ Str,
     put_(X#string{obj = Res, len = length(Res)}),
     Res.

So, if modification of the module attribute was possible,
then I guess get_/0 and put_/0 could be implemented as:

-store([]).

get_() ->
     dict:fetch(THIS, module_info(store)).

put_(NewObj) ->
     module_info(store, dict:store(THIS, NewObj, module_info(store)).

init_() ->
     module_info(store, dict:new()),
     ...as before...


Cheers, Tobbe




More information about the erlang-questions mailing list