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

在Erlang消息上可以发送什么类型的消息?,erlang,otp,gen-server,Erlang,Otp,Gen Server,我主要想知道我是否可以在分布式Erlang设置中在消息中发送函数 在机器1上: F1 = Fun()-> hey end, gen_server:call(on_other_machine,F1) handler_call(Function,From,State) -> {reply,Function(),State) 在机器2上: F1 = Fun()-> hey end, gen_server:call(on_other_machine,F1) handler_c

我主要想知道我是否可以在分布式Erlang设置中在消息中发送函数

在机器1上:

F1 = Fun()-> hey end,

gen_server:call(on_other_machine,F1)
handler_call(Function,From,State) ->
{reply,Function(),State)
在机器2上:

F1 = Fun()-> hey end,

gen_server:call(on_other_machine,F1)
handler_call(Function,From,State) ->
{reply,Function(),State)

这有意义吗?

您可以发送任何有效的Erlang术语。尽管你在发送FUN时必须小心。任何引用模块内函数的乐趣都需要该模块存在于目标节点上才能工作:

(first@host)9> rpc:call(second@host, erlang, apply,
                        [fun io:format/1, ["Hey!~n"]]).
Hey!
ok
(first@host)10> mymodule:func("Hey!~n").
5
(first@host)11> rpc:call(second@host, 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会生成一个
unde
异常。

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

[…]您可能知道,Erlang分布 通过发送二进制编码工作 条款的修改;因此,发送一个有趣的消息也是非常重要的 基本上是通过使用 erlang:term_to_binary/1;通过 将生成的二进制文件发送到另一个节点,以及 然后使用 erlang:binary-to-term/1。[…] 这是很明显的 对于大多数数据类型;但它是如何实现的呢 为函数对象工作

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

[…]未传递函数的定义;只要有足够的信息在其他节点(如果模块在那里)重新创建乐趣

[…]如果包含乐趣的模块尚未加载,且目标节点正在交互模式下运行;然后尝试使用常规模块加载机制(包含在模块错误处理程序中)加载模块;然后,它尝试查看在所述模块中是否存在具有给定id的乐趣。但是,只有当您尝试应用该函数时,这种情况才会缓慢发生

[…]如果您从未尝试应用该函数,则不会发生任何不好的情况。乐趣可以传递到另一个节点(其中有模块/乐趣),然后每个人都会感到高兴。 可能目标节点有一个加载了所述名称的模块,但可能在不同版本中;这很可能会有一个不同的MD5校验和,如果你尝试应用它,那么你会得到错误badfun


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

至于匿名函数,它们似乎可以按预期发送和工作

t1@localhost:

(t1@localhost)7> register(shell, self()).
true
(t1@localhost)10> A = me, receive Fun when is_function(Fun) -> Fun(A) end.
hello me you
ok
(t2@localhost)11> B = you.
you
(t2@localhost)12> Fn2 = fun (A) -> io:format("hello ~p ~p~n", [A, B]) end.
#Fun<erl_eval.6.54118792>
(t2@localhost)13> {shell, 't1@localhost'} ! Fn2.
t2@localhost:

(t1@localhost)7> register(shell, self()).
true
(t1@localhost)10> A = me, receive Fun when is_function(Fun) -> Fun(A) end.
hello me you
ok
(t2@localhost)11> B = you.
you
(t2@localhost)12> Fn2 = fun (A) -> io:format("hello ~p ~p~n", [A, B]) end.
#Fun<erl_eval.6.54118792>
(t2@localhost)13> {shell, 't1@localhost'} ! Fn2.
(t2@localhost)11> B=你。
你
(t2@localhost)12> Fn2=fun(A)->io:format(“hello~p~p~n,[A,B])结束。
#乐趣
(t2@localhost)13> {shell,'t1@localhost'} ! Fn2。
我正在为一个基于riak core的应用程序添加覆盖逻辑,如果匿名函数不能用于消息,那么合并收集的结果可能会很棘手

也请查看


我猜riak_kv可能是用它来过滤结果。

匿名函数呢?如果你是说匿名函数,它也有同样的问题。即,定义它的模块必须存在于远程节点上。