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