[erlang-questions] Can Mnesia/ets/dets store functions?

Matthias Lang <>
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