First:
-module(some_mod).
-compile(export_all).
some_fun() ->
fun f/0.
f() ->
ok.
Second:
-module(some_mod).
-compile(export_all).
some_fun() ->
fun ?MODULE:f/0.
f() ->
ok.
I encountered this change during a hot code upgrade. What is the the difference between fun ?MODULE:f/0
and fun f/0
?
From Erlang documentation:
A fun created by
fun M:F/A
is called an external fun. Calling it will always call the functionF
with arityA
in the latest code for moduleM
. Notice that moduleM
does not even need to be loaded when the funfun M:F/A
is created.All other funs are called local fun. When a local fun is called, the same version of the code that created the fun is called (even if a newer version of the module has been loaded).
They have different behaviours in code upgrading as the documentation says. Your first module uses a local function (fun f/0
) and the second one uses an external function (fun ?MODULE:f/0
which in preprocessing replaced with fun some_mod:f/0
).
So if you upgrade your first module (which uses local function), the processes that are using some_fun
function, don't use the newer version. But if you upgrade the second module (which uses external function), the latest version of code will be called whenever some_fun
is called from inside processes which were spawned even before the loading of new version.
Notice: There can be just two versions of a module, old and new. If a third version of the module is loaded, the code server removes (purges) the old code and any processes lingering in it is terminated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With