在erlang消息上可以发送什么类型的消息?

问题描述:

主要我想知道是否可以在分布式erlang安装程序的消息中发送函数。在erlang消息上可以发送什么类型的消息?

机器1

F1 = Fun()-> hey end, 

gen_server:call(on_other_machine,F1) 

上机2

handler_call(Function,From,State) -> 
{reply,Function(),State) 

有意义吗?

Here是一篇关于“将乐趣传递给其他Erlang节点”的有趣文章。简要地恢复它:

[...]正如你可能知道,Erlang分布 通过发送方面的二进制编码 工程;所以发送一个乐趣也是 基本上是通过使用 erlang:term_to_binary/1对其进行编码完成的;将 生成的二进制传递给另一个节点,然后使用 再次对其进行解码,使用 erlang:binary_to_term/1。 对于大多数数据类型,这是非常明显的 ;但是 如何用于函数对象?

当你编码一个有趣的东西时,编码的 只是对函数的引用,而不是函数的实现。 [...]

函数的定义不会传递;如果模块在那里,就足够的信息来重新创建其他节点的乐趣。

[...]如果包含fun的模块尚未加载,并且目标节点以交互模式运行;然后尝试使用常规模块加载机制(包含在模块error_handler中)加载模块;然后它试图查看在所述模块中是否有给定ID的乐趣。但是,只有在尝试应用该功能时才会发生这种情况。

[...] [...]如果你从来没有尝试应用这个函数,那么没有什么不好的事情发生。乐趣可以传递给另一个节点(它有问题的模块/乐趣),然后每个人都很开心。 也许目标节点有一个装载了所述名称的模块,但可能是不同的版本;然后很可能会有不同的MD5校验和,那么如果您尝试应用它,则会出现错误badfun。

我建议你阅读整篇文章,因为它非常有趣。

您可以发送任何有效的Erlang术语。虽然发送乐趣时你必须小心。什么好玩的引用模块内部的功能需要与模块到目标节点上存在的工作:

([email protected])9> rpc:call([email protected], erlang, apply, 
         [fun io:format/1, ["Hey!~n"]]). 
Hey! 
ok 
([email protected])10> mymodule:func("Hey!~n"). 
5 
([email protected])11> rpc:call([email protected], erlang, apply, 
         [fun mymodule:func/1, ["Hey!~n"]]). 
{badrpc,{'EXIT',{undef,[{mymodule,func,["Hey!~n"]}, 
         {rpc,'-handle_call_call/6-fun-0-',5}]}}} 

在这个例子中,io存在两个节点上和它的作品从io发送功能的乐趣。但是,mymodule仅存在于第一个节点上,并且fun在另一个节点上调用时会生成undef异常。

+0

匿名函数呢? – Federico 2011-05-24 19:24:42

+0

如果你认为你的名字是匿名的,那么它有同样的问题。即它定义的模块必须存在于远程节点上。 – Lukas 2011-05-24 20:10:13

至于匿名功能,看起来他们可以发送和按预期工作。

T1 @本地:

([email protected])7> register(shell, self()). 
true 
([email protected])10> A = me, receive Fun when is_function(Fun) -> Fun(A) end. 
hello me you 
ok 

T2 @本地:

([email protected])11> B = you. 
you 
([email protected])12> Fn2 = fun (A) -> io:format("hello ~p ~p~n", [A, B]) end. 
#Fun<erl_eval.6.54118792> 
([email protected])13> {shell, '[email protected]'} ! Fn2. 

我加入覆盖逻辑建立在了Riak核心的应用程序,以及合并结果的聚集可如果匿名函数不能在消息中使用,就很棘手。

还检查了riak_kv/src/riak_kv_coverage_filter.erl

riak_kv可能会使用它来filter结果,我猜。