%% Save this as bar.erl.
%% Run c(bar), bar:start().
%% The process will repeatedly loop printing what version ("old")
%% of the code it's using.
%% Change the VER macro to "new", and run c(bar) again.
%% "loop", "local directly", and "local indirectly" will continue
%% printing "old"; others will switch to "new".
%%
%% My understanding: "loop" and all four "local" calls should continue
%% printing "old"; "external" calls should print "new".
%% (Also, notice the compiler optimizes ``(fun foo/1)(...)'' to ``foo(...)'',
%% which has different semantics.)
-module(bar).
-export([start/0, loop/2, foo/1]).
-define(VER, "old").
start() ->
spawn_link(?MODULE, loop, [fun foo/1, fun ?MODULE:foo/1]).
loop(LocalFoo, ExternalFoo) ->
io:format("~n" ++ ?VER ++ " loop~n"),
foo("local directly"),
(fun foo/1)("local indirectly"),
X = fun foo/1, X(io_lib:format("local indirectly via ~p", [X])),
LocalFoo("local indirectly from start"),
?MODULE:foo("external directly"),
(fun ?MODULE:foo/1)("external indirectly"),
Y = fun ?MODULE:foo/1, Y(io_lib:format("external indirectly via ~p", [Y])),
ExternalFoo("external from start"),
timer:sleep(3000),
loop(LocalFoo, ExternalFoo).
foo(How) ->
io:format(?VER ++ " foo (~s)~n", [How]).