[erlang-questions] funs versus code loading

Sam Bobroff <>
Fri May 13 06:52:19 CEST 2011


Thanks for taking a look at this :-)

On 13 May 2011 14:44, Daniel Dormont <> wrote:

> 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.
>

Yes, unsurprising because doing an explicit "external" call is supposed to
transition into the newest code version.

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}"
>

This isn't too surprising to me: code:load_file() does not do an implicit
code:purge() and that error is normal in that case. Because there is an old
version of the module loaded, you need to do code:purge(foo) before you can
issue another code:load_file().

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 :)
>

I can answer that one: l() does an implicit code:purge() (although it
doesn't say so in it's little help description).


> dan
>
> On Thu, May 12, 2011 at 10:16 PM, Sam Bobroff <> 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
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110513/3cc74880/attachment.html>


More information about the erlang-questions mailing list