I'm a beginner at erlang programming. To understand hot code loading better, I used the example from Wikipedia (I added responses to the sending Pid for debugging):
%% A process whose only job is to keep a counter.
%% First version
-module(counter).
-export([start/0, codeswitch/2]).
start() -> loop(0).
loop(Sum) ->
receive
{increment, Count} ->
loop(Sum+Count);
%% modified code, which will be loaded:
% reset ->
% loop(0);
{counter, Pid} ->
Pid ! {counter, Sum},
loop(Sum);
{code_switch, Pid} ->
Pid ! {switch, Sum},
?MODULE:codeswitch(Pid, Sum)
% Force the use of 'codeswitch/2' from the latest MODULE version
end.
codeswitch(FromPid, Sum) ->
FromPid ! {switched, Sum},
loop(Sum).
All is good. I can load the module via c(counter).
in the shell, spawn a new process via Pid = spawn(fun counter:start/0).
and send messages to the spawned process. When I now add a new pattern to the receive expression reset -> loop(0)
and reload the code via c(counter).
, everything works as expected, new code is loaded, Sum
keeps its incremented value etc.
But when I send the {code_switch, self()}
message, Sum
gets reset to 0 when loop(Sum)
is called (FromPid ! {switched, Sum}
in the call to FromPid ! {switched, Sum}
still returns correct state).
What am I missing, why does my state go away after the first call to an codeswitched function?
Thanks for your help!
| 18 | Pid ! {counter, self()}.
{counter,<0.49.0>}
| 19 | flush().
Shell got {counter,6}
ok
| 20 | Pid ! {code_switch, self()}.
{code_switch,<0.49.0>}
| 21 | flush().
Shell got {switch,6}
Shell got {switched,6}
ok
| 22 | Pid ! {counter, self()}.
{counter,<0.49.0>}
| 23 | flush().
Shell got {counter,0}
ok
I put io:format("DebugInfo:~p~n", [Sum])
as the first expression in loop
. Result is:
12> Pid ! {code_switch, self()}.
DebugInfo:3
{code_switch,<0.33.0>}
DebugInfo:0
13> flush().
Shell got {switch,3}
Shell got {switched,3}
ok
EDIT: I found that when I spawn the process via spawn/3
, aka spawn(counter, start, []).
, this works. When I spawn the process via spawn/1
, aka spawn(fun counter:start/0)
, this doesn't
work. Is this expected behavior? What am I missing?
Documentation states for spawn/1
:
Returns the process identifier of a new process started by the application of Fun to the empty list []. Otherwise works like spawn/3.
EDIT: .... Aaaand after trying to replicate this on an Ubuntu virtual machine (where it didn't happen), I am now also unable to reproduce this (and will test my memory for corruption now..)