[erlang-questions] Can Mnesia/ets/dets store functions?
Matthias Lang
matthias@REDACTED
Sun May 24 09:27:07 CEST 2009
On Friday, May 22, Cameron Kerr wrote:
> I know Mnesia/ets/dets can store any arbitrary Erlang term, but does
> this include funs?
Yes.
> Any complications with that?
One possible source of surprises is that funs created in modules are
part of the module, so the fun can change if the code does. Example:
-module(ck).
-export([make_fun/0]).
make_fun() ->
fun() -> 66 end.
1> c(ck).
{ok,ck}
2> F = ck:make_fun().
#Fun<ck.0.47723623>
3> F().
66
4> file:write_file("/tmp/fun_in_file", term_to_binary(F)).
ok
And now terminate Erlang, edit 'ck' (for instance make the fun return
67) and start a new emulator:
1> c(ck).
{ok,ck}
2> {ok, Bin} = file:read_file("/tmp/fun_in_file").
{ok,<<131,112,0,0,0,67,0,36,164,242,79,154,121,7,194,27,...
3> F = binary_to_term(Bin).
#Fun<ck.0.47723623>
4> F().
** exception error: bad function #Fun<ck.0.47723623>
What happened? The fun I stored is a reference to a fun which no
longer exists. The fun no longer exists because I changed the
module. I demonstrated it using a file and restarting the emulator,
but the same applies to other means of storing (e.g. dets) or sending
funs, including sending funs around in distributed Erlang (e.g. mnesia).
In the above example, Erlang did the right thing, i.e. it detected
that the fun had been changed. Due to a long-standing flaw, it's also
possible to change a fun without Erlang realising:
http://www.erlang.org/pipermail/erlang-bugs/2007-June/000368.html
Matt
More information about the erlang-questions
mailing list