<div>Thanks for taking a look at this :-)</div><div><br></div>On 13 May 2011 14:44, Daniel Dormont <span dir="ltr"><<a href="mailto:dan@greywallsoftware.com">dan@greywallsoftware.com</a>></span> wrote:<br><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">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.<br>
<br>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.<br>
</blockquote><div> </div><div>Yes, unsurprising because doing an explicit "external" call is supposed to transition into the newest code version.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
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 ===<br>Loading of /Users/dan/foo.beam failed: not_purged<br>{error,not_purged}"<br>
</blockquote><div><br></div><div>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().</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">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 :)<br>
</blockquote><div><br></div><div>I can answer that one: l() does an implicit code:purge() (although it doesn't say so in it's little help description).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
dan<br><br><div class="gmail_quote">On Thu, May 12, 2011 at 10:16 PM, Sam Bobroff <span dir="ltr"><<a href="mailto:sam@m5net.com" target="_blank">sam@m5net.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left:1px solid rgb(204, 204, 204);margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">Hi all,<div><br></div><div>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:</div>


<div><br></div><div>It appears that when:</div><div>* Executing a Fun,</div><div>* that contains a local function call,</div><div>* in a process running in the old code of a module that has both current and old versions loaded,</div>


<div>* the local function call will sometimes go to the current code and sometimes go to the old code.</div><div><br></div><div>It appears that the decision is based somehow on the content of the code in the current version.</div>


<div><br></div><div>Obviously an example is in order:</div><div><br></div><div>--- begin foo.erl ---</div><div><div>-module(foo).</div><div>-ifdef(BODY).</div><div>-export([start/0, loop/0]).</div><div>start() -></div>


<div>        register(?MODULE, spawn(?MODULE, loop, [])).</div><div>loop() -></div><div>        io:fwrite("loop version ~p\n", [?V]),</div><div>        receive</div><div>                _ -></div><div>                        F = fun () -> loop() end,</div>


<div>                        F()</div><div>        end.</div><div>-endif.</div></div><div>--- end foo.erl ---</div><div><br></div><div>Armed with this file, we can do this:</div><div><br></div><div><div>$ erl</div><div>Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]</div>


<div><br></div><div>Eshell V5.8.3  (abort with ^G)</div><div>1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).</div><div>{ok,foo,[]}</div><div>2> foo:start().</div><div>loop version 1</div>

<div>
true</div><div>3> compile:file("foo", [{d,'BODY'}, {d,'V',2}]).</div><div>{ok,foo,[]}</div><div>4> code:load_file(foo).</div><div>{module,foo}</div><div>5> foo ! x.</div><div>loop version 2</div>


<div>x</div></div><div><br></div><div>The local function call in the Fun has called from the old version into the current version of the module (not what I expected).</div><div>Run the same sequence again but this time load a module that is empty:</div>


<div><br></div><div><div>$ erl</div><div>Erlang R14B02 (erts-5.8.3) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]</div><div><br></div><div>Eshell V5.8.3  (abort with ^G)</div><div>1> compile:file("foo", [{d,'BODY'}, {d,'V',1}]).</div>


<div>{ok,foo,[]}</div><div>2> foo:start().</div><div>loop version 1</div><div>true</div><div>3> compile:file("foo", [{d,'V',2}]).</div><div>{ok,foo,[]}</div><div>4> code:load_file(foo).</div><div>


{module,foo}</div><div>5> foo ! x.</div><div>loop version 1</div><div>x</div></div><div><br></div><div>The local function call in the Fun has stayed in the old version of the module (actually what I expected).</div><div>


<br></div><div>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.</div><div><br></div><div>My system is Ubuntu 11.04 running Erlang R14B02 and I haven't yet checked older versions of Erlang for the same behaviour.</div>


<div><br></div><div>Thanks,</div><div>Sam.</div>
<br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br>
</blockquote></div><br>