Just another Mnesia question.

Ulf Wiger ulf.wiger@REDACTED
Mon Apr 26 23:03:50 CEST 1999


Craig Dickson wrote:
> 
> 
> Another question for the experts: does the idea of storing "arbitrary Erlang
> terms" in the database imply that not only data (numbers, text, lists) but
> also executable code (i.e. funs) can be stored in the database?

Actually, with the new BEAM, you should be able to do this reasonably
safely. JAM is not very good at handling funs when a module is
recompiled. Usually, recompiling a module meant that funs could no
longer be called. With BEAM, this is no longer true.

You still have to do this with care, though. As far as I know, the only
thing stored in the database is a reference to a certain function object
in a given module (note: *not* the actual code). While I haven't been
able to break the BEAM implementation of funs, I would like to hear
someone explain exactly what its limitations are.

With the old JAM 4.7, the answer is: don't do it.

%%%%%%%%%%%%%%%% example program
-module(test).
-export([store/1, run/1]).

store(a) ->
    mnesia:dirty_write({test, a, fun() -> fun_a end});
store(b) ->   
    mnesia:dirty_write({test, b, fun() -> fun_b end}).

run(a) ->
    [{_, a, F}] = mnesia:dirty_read({test,a}),
    F();
run(b) ->
    [{_, b, F}] = mnesia:dirty_read({test,b}),
    F().

%%%%%%%%%%%%%%%% end example program

(bbs@REDACTED)5> test:store(a).
ok
(bbs@REDACTED)6> test:store(b).
ok

	(Recompile test, restart mnesia)

(bbs@REDACTED)3> test:run(a).
fun_a
(bbs@REDACTED)4> test:run(b).
fun_b

It seemed to work even though I moved the fun definitions around.
Further inspection:

(bbs@REDACTED)2> Res = mnesia:dirty_read({test,a}).
[{test,a,#Fun<test>}]
(bbs@REDACTED)3> erlang:display(Res).
[{test,a,{fun,test,0,12375923,{}}}]


When I look at the output of c(test, ['E']):
-----------------------------------------
store(b) ->
    mnesia:dirty_write({test,b,make_fun('fun%0'/0, 0, 125669168, [])});
store(a) ->
    mnesia:dirty_write({test,a,make_fun('fun%1'/0, 1, 67946889, [])}).
 
run(a) ->
    [{_,a,F}] = mnesia:dirty_read({test,a}),
    F();
run(b) ->
    [{_,b,F}] = mnesia:dirty_read({test,b}),
    F().
 
'fun%0'() ->
    fun_b.
 
'fun%1'() ->
    fun_a.
-----------------------------------------
 
I don't know how the numbers 125669168 and 67946889 are derived.
Checksums?

/Uffe
-- 
Ulf Wiger, Chief Designer AXD 301     <ulf.wiger@REDACTED>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuvägen 9, Älvsjö                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44



More information about the erlang-questions mailing list