<!DOCTYPE html><html><head><style type="text/css">body { font-family:'Helvetica'; font-size:12px}</style></head><body><div>Hi,<br><br>If you compile the module with the 'E' option you can see the actual code generated for module_info/0,1:<br><br><font face="'Menlo',monospace">module_info() -></font><font face="'Menlo',monospace"><br></font><font face="'Menlo',monospace"> erlang:get_module_info(loopie).<br></font><font face="'Menlo',monospace"><br></font><font face="'Menlo',monospace">module_info(X) -><br></font><font face="'Menlo',monospace"> erlang:get_module_info(loopie, X).</font><br><br>This means the compiler doesn't implement the function by hard coding the results, but via caling a BIF instead. And the BIF always uses the <a href="https://github.com/erlang/otp/blob/0481ecafa24dc60c6bca8afdda038dc2239c991d/erts/emulator/beam/beam_load.c#L5114">current version</a> of the module. Which, I personally think, is OK and consistent with the rest of OTP: if you would e.g. print the result of <font face="'Menlo',monospace">code:get_object_code(?MODULE)</font> it would also reflect the current version.</div><div><br></div><div>However, I think this behaviour of <font face="'Menlo',monospace">module_info</font> is not documented properly. The "compiler will hard code the results in the module" would be a valid mental model too, especially since <font face="'Menlo',monospace">erlang:get_module_info/1,2</font> functions aren't documented either. So I'd raise a bug report on the documentation.</div><div><br></div><div>BR,</div><div>Daniel</div><div><br>On Tue, 26 Nov 2013 19:43:09 -0000, Fred Youhanaie <fly@anydata.co.uk> wrote:<br><br>> Hi<br>><br>> I'm playing with a simple piece of code where I switch versions via erl <br>> shell.<br>><br>> Curiously I noticed that as soon as I load a new version of the module, <br>> module_info/1 returns the attribute of the currently loaded version <br>> rather than the version for the running process!<br>><br>> Is this intentional?<br>><br>> Code and sample session is at the bottom.<br>><br>> Thanks<br>><br>> Fred<br>><br>> Here's the code:<br>><br>> -module(loopie).<br>> -compile([export_all]).<br>> start() -><br>> start(5000).<br>> start(T) -><br>> register(loopie, spawn(?MODULE, loop, [T])).<br>> loop(T) -><br>> receive<br>> switch -><br>> io:format("switched~n"),<br>> loopie:loop(T);<br>> ANY -><br>> io:format("received unexpected message >~p<.~n", [ANY]),<br>> loop(T)<br>> after T -><br>> io:format("v1 ~p.~n", [module_info(attributes)]),<br>> loop(T)<br>> end.<br>><br>> Here's a sample session:<br>><br>> 1. initially loopie prints v1 and vsn every 5 seconds.<br>> 2. on the source "v1" is changed to "v2" and module is compiled and <br>> loaded<br>> 3. loopie is now printing v1 but with the new vsn<br>> 4. switch message is sent<br>> 5. loopie is now printing v2 and the new vsn<br>><br>> $ erl<br>> Erlang R16B02 (erts-5.10.3) [source] [async-threads:10] [hipe] <br>> [kernel-poll:false]<br>><br>> Eshell V5.10.3 (abort with ^G)<br>> 1> l(loopie).<br>> {module,loopie}<br>> 2> loopie:start().<br>> true<br>> v1 [{vsn,[102112148784636006663528886950745967476]}].<br>> v1 [{vsn,[102112148784636006663528886950745967476]}].<br>> 3> l(loopie).<br>> {module,loopie}<br>> v1 [{vsn,[337256366447556252629333013282189761649]}].<br>> v1 [{vsn,[337256366447556252629333013282189761649]}].<br>> v1 [{vsn,[337256366447556252629333013282189761649]}].<br>> 4> loopie!switch.<br>> switched<br>> switch<br>> v2 [{vsn,[337256366447556252629333013282189761649]}].<br>> v2 [{vsn,[337256366447556252629333013282189761649]}].<br>> 5><br>> _______________________________________________<br>> erlang-questions mailing list<br>> erlang-questions@erlang.org<br>> <a href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a><br><br><br></div></body></html>