遭遇Erlang版的classloader问题
如下的简单代码:
下载: t1.erl
-module(t1).
-export([test/0]).
test() ->
io:format("this is a test~n").
-export([test/0]).
test() ->
io:format("this is a test~n").
我们做如下的操作:
$> erlc t1.erl
$> erl
1> erlang:function_exported(t1, test, 0).
false
2> t1:test().
this is a test
ok
3> erlang:function_exported(t1, test, 0).
true
$> erl
1> erlang:function_exported(t1, test, 0).
false
2> t1:test().
this is a test
ok
3> erlang:function_exported(t1, test, 0).
true
第二行的操作 t1:test(). 是成功的。这也从侧面证明了当前路径“.”是在 erl 的 ebin path 之中,而 erlang 会自动的加载这个 module 。
问题在于:第一次调用 erlang:function_exported(t1, test, 0). 返回 false 。第二次调用 erlang:function_exported(t1, test, 0). 又返回了 true 。
这也许说明 erlang 是在第一次调用某个方法时,动态的加载相应的 beam 文件。可是,对于依赖于 erlang:function_exported 方法的代码来说(比如,当我需要根据输入参数调用不同的方法),又如何能预先知道某个 module 是否已经被 load 进入 runtime 了呢?
BIF erlang:module_loaded(Module) 提供了一条线索。可以通过这个方法来判断一个 module 是否已经加载。此外,erlang:load_module(Module, Bin) 也提供了从二进制的字节码加载一个 module 的方法。但是,莫非要我自己动手来写根据一个 name 来搜索 ebin path 并从中 load 一个 module 字节码的方法么?
晕。。。(待解决)


Comments
ok,通过 gotApi.com 提供的强大 erlang 文档搜索功能,瞬间就找到了问题的解决方案。如下:
正如我所期望的,这个方法以 Mod 为参数处理加载过程,帮我完成 ebin path 的搜索步骤。
古人云,工欲善其事,必先利其器。诚不我欺(erlang 的文档确实不如 gotApi 好用啊)。
gotapi的确是一旦拥有别无所求:^)
默认的情况 erlang实在第一次看到模块使用的时候 才去加载模块的哦
System Principles 文档写着:
1.4 Code Loading Strategy
The runtime system can be started in either embedded or interactive mode. Which one is decided by the command line flag -mode.
% erl -mode embedded
Default mode is interactive.
* In embedded mode, all code is loaded during system start-up according to the boot script. (Code can also be loaded later by explicitly ordering the code server to do so).
* In interactive mode, code is dynamically loaded when first referenced. When a call to a function in a module is made, and the module is not loaded, the code server searches the code path and loads the module into the system.
Initially, the code path consists of the current working directory and all object code directories under ROOT/lib, where ROOT is the installation directory of Erlang/OTP. Directories can be named Name[-Vsn] and the code server, by default, chooses the directory with the highest version number among those which have the same Name. The -Vsn suffix is optional. If an ebin directory exists under the Name[-Vsn] directory, it is this directory which is added to the code path.
还有code:clash(). 能够检查模块加载是否冲突。
http://mryufeng.javaeye.com
Write a Comment