在Erlang中使用完全限定的函数调用?

时间:2015-10-03 13:16:09

标签: erlang fully-qualified-naming

我刚学会了如何在Erlang中升级模块,我知道只有使用完全限定名称的函数调用(例如。module:function())才会“重新链接”到加载到VM中的当前版本,但是没有指定模块名称的函数调用不会“重新链接”到当前版本,而是继续使用旧版本。

是否有关于何时使用完全限定函数调用以及何时可以通过其名称调用函数的经验法则?使用全名调用所有函数(如module:function())?

是一个坏主意

1 个答案:

答案 0 :(得分:7)

Erlang应用程序通常使用标准行为,如gen_servergen_fsm,它们已在其内部循环中包含完全限定的函数调用,因此请注意此问题。

但是如果出于某种原因你不得不用自己的递归消息处理循环编写自己的模块并且你希望该模块在运行时可以升级,那么循环需要包含一个完全限定的递归调用,通常你需要&# 39; d将其置于处理特定升级消息的代码段中,类似于与标准行为一起使用的回调模块中预期的code_change/3 function

例如,考虑下面的循环,它类似于标准行为的循环,但大大简化了:

loop(Callbacks, State) ->
    {{Next, NState},DoChange} =
        receive
            {code_change, ChangeData} ->
                {Callbacks:handle_code_change(ChangeData, State), true};
            {cast,Data} ->
                {Callbacks:handle_cast(Data,State), false};
            {call,From,Data} ->
                Result = Callbacks:handle_call(Data,State),
                case Result of
                    {reply, Reply} ->
                        From ! Reply;
                    _ ->
                        ok
                end,
                {Reply, false};
            Message ->
                {Callbacks:handle_info(Message,State), false}
        end,
    case Next of
        stop -> ok;
        _ ->
            case DoChange of
                true -> ?MODULE:loop(Callbacks, NState);
                false -> loop(Callbacks, NState)
            end
    end.

loop/2函数有两个参数:Callbacks,期望导出为特定消息调用的特定函数的回调模块的名称,以及State,它对循环不透明但是可能对回调模块有意义。循环是尾递归的,它通过调用特定的回调函数来处理几个特定的​​消息,然后通过调用回调模块中的handle_info/2来处理任何其他消息。 (如果您已经使用了标准行为,那么您会发现这种方法很熟悉。)回调函数返回一个Next值,以及一个要传递给下一个循环的新状态。如果Nextstop,我们会退出循环,否则我们会检查DoChange的值,该值仅针对代码更改消息设置为true,如果&#39} ; s true循环使用完全限定的调用调用自身,否则它只使用常规调用。

如前所述,这一切都大大简化了。您需要编写自己的循环是非常罕见的,如果您这样做,还有其他重要的事情,例如system messages,您需要处理。你最好使用标准行为。