如何加载实现相同行为的多个模块

时间:2019-12-30 04:24:42

标签: import module erlang

我不明白应该如何使用多个模块,每个模块都实现相同的行为,因为在编译时会收到此错误:

  

功能已从导入

就我而言,我有两个实现gen_event行为的模块,我试图将它们导入第三个模块。 每当我尝试编译此代码时,我都会收到错误消息:

-module(mgr).
-import(h1,[init/1]).   // implements gen_event
-import(h2,[init/1]).   // implements gen_event

1 个答案:

答案 0 :(得分:3)

您不能那样做。导入是避免编写函数的完整“定义”的简单技巧。它什么也没做,只是对编译器说:在此模块中看到init(P)时,请替换为h1:init(P)

因此,无法导入多个具有相同名称/名称的函数。

对于短名称,使用导入没有任何好处。

如果您使用带有长名称的module:function,并且想要缩短代码中的行,则可以改用宏,并且没有限制(但函数名称相同的可能性很小) :o):

-define(Func1(Var1,...,VarN), module1:func(Var1,...,VarN)). 
-define(Func2(Var1,...,VarN), module2:func(Var1,...,VarN)). 
...
?Func1(A1,...,AN);
...
?Func2(B1,...,BN);

修改

下一个示例说明了它是如何工作的,首先我按如下方式创建模块mod1:

-module (mod1).

-export ([test/1]).

test(P) ->
    case P of 
        1 -> ok;
        2 -> mod2:test()
    end.

然后在外壳中对其进行测试:

1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.

mod2创建为:

-module (mod2).

-export ([test/0]).

test() ->
    io:format("now it works~n").

在外壳中继续:

4> c(mod2).
{ok,mod2}
5> mod1:test(1).                                   
ok
6> mod1:test(2).                                   
now it works
ok
7> 

如您所见,不必修改mod1,而只需创建和编译mod2(请注意,如果mod2已经存在,但函数test / 0为未导出)。

如果要验证代码未使用未定义函数,则可以使用外部工具。在使用rebar3管理项目时,我使用rebar3 xref命令执行此检查。请注意,调用未定义的函数只是一个简单的警告,它在应用程序升级的上下文中是有意义的。该验证不是防弹的:在构建时完成,这并不能保证在生产系统上具有正确版本的情况下将提供您需要的模块:它带来了很多有关版本控制和代码加载的有趣问题。