[erlang-questions] parameterized modules and OO
Torbjorn Tornkvist
tobbe@REDACTED
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