[erlang-questions] funs versus code loading
Daniel Dormont
dan@REDACTED
Fri May 13 06:44:51 CEST 2011
I'm far from an expert, but I repeated your test just for fun on R12B and
got the same result. I did a few other tests as well.
Perhaps unsurprisingly, changing "loop()" to "foo:loop()" produced the same
result in test 1 and an error {undef,[{foo,loop,[]}]} in test 2. That is,
the old code seems to be fully discarded in that case.
Maybe more surprisingly, loading the code for a third time in test 1 results
in an error "=ERROR REPORT==== 13-May-2011::00:13:18 ===
Loading of /Users/dan/foo.beam failed: not_purged
{error,not_purged}"
However, using the shell command l/1 instead of code:load_file/1 avoids this
error. I'll leave it to the experts to tell us why :)
dan
On Thu, May 12, 2011 at 10:16 PM, Sam Bobroff <sam@REDACTED> wrote:
> Hi all,
>
> I've encountered a situation that makes my brain hurt and I was wondering
> if anyone could help me understand it. It's so strange that it may be a bug,
> if so please let me know and I'll do whatever groundwork is necessary to get
> it tracked down. Anyway on to the situation:
>
> It appears that when:
> * Executing a Fun,
> * that contains a local function call,
> * in a process running in the old code of a module that has both current
> and old versions loaded,
> * the local function call will sometimes go to the current code and
> sometimes go to the old code.
>
> It appears that the decision is based somehow on the content of the code in
> the current version.
>
> Obviously an example is in order:
>
> --- begin foo.erl ---
> -module(foo).
> -ifdef(BODY).
> -export([start/0, loop/0]).
> start() ->
> register(?MODULE, spawn(?MODULE, loop, [])).
> loop() ->
> io:fwrite("loop version ~p\n", [?V]),
> receive
> _ ->
> F = fun () -> loop() end,
> F()
> end.
> -endif.
> --- end foo.erl ---
>
> Armed with this file, we can do this:
>
> $ erl
> Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0]
> [hipe] [kernel-poll:false]
>
> Eshell V5.8.3 (abort with ^G)
> 1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).
> {ok,foo,[]}
> 2> foo:start().
> loop version 1
> true
> 3> compile:file("foo", [{d,'BODY'}, {d,'V',2}]).
> {ok,foo,[]}
> 4> code:load_file(foo).
> {module,foo}
> 5> foo ! x.
> loop version 2
> x
>
> The local function call in the Fun has called from the old version into the
> current version of the module (not what I expected).
> Run the same sequence again but this time load a module that is empty:
>
> $ erl
> Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0]
> [hipe] [kernel-poll:false]
>
> Eshell V5.8.3 (abort with ^G)
> 1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).
> {ok,foo,[]}
> 2> foo:start().
> loop version 1
> true
> 3> compile:file("foo", [{d,'V',2}]).
> {ok,foo,[]}
> 4> code:load_file(foo).
> {module,foo}
> 5> foo ! x.
> loop version 1
> x
>
> The local function call in the Fun has stayed in the old version of the
> module (actually what I expected).
>
> Some changes other than emptying the body of the module seem to have a
> similar effect but I haven't tracked down exactly what the trigger is.
>
> My system is Ubuntu 11.04 running Erlang R14B02 and I haven't yet checked
> older versions of Erlang for the same behaviour.
>
> Thanks,
> Sam.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110513/21e4b043/attachment.htm>
More information about the erlang-questions
mailing list