在Erlang中使用完全限定的函数调用? [英] Using fully qualified function calls in Erlang?

查看:206
本文介绍了在Erlang中使用完全限定的函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have just learnt how to upgrade a module in Erlang and I know that only the function calls that use the fully qualified names (eg. module:function()) gets "relinked" to the current version loaded into the VM, but the function calls that do not specify the module's name do not get "relinked" to the current version, but keep using the older one.

在何时使用完全限定的函数调用以及何时可以仅按名称调用函数方面是否存在经验法则?用全名(例如module:function())调用所有函数不是一个好主意吗?

Is there a rule of thumb on when to use a fully qualified function call and when it's OK to call a function just by its name? Is it a bad idea to call all functions using their full name (like module:function())?

推荐答案

Erlang应用程序通常会使用 gen_server gen_fsm ,它们内部已包含完全限定的函数调用循环,因此请注意这个问题.

Erlang applications normally make use of standard behaviors like gen_server and gen_fsm, which already contain fully qualified function calls within their internal loops and so take care of this issue.

但是,如果由于某种原因,您不得不使用自己的递归消息处理循环来编写自己的模块,并且希望该模块在运行时可升级,则该循环需要包含一个完全合格的递归调用,通常情况下, d将其放置在处理特定升级消息的一段代码中,类似于 code_change/3函数在具有标准行为的回调模块中是预期的.

But if for some reason you feel compelled to write your own module with its own recursive message-handling loop and you want that module to be upgradeable at runtime, the loop needs to contain a fully qualified recursive call, and normally you'd place this within a section of code handling a specific upgrade message, similar to the code_change/3 function expected in a callback module used with a standard behavior.

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

For example, consider the loop below, which is similar to those of the standard behaviors but greatly simplified:

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,如果是,则循环使用完全限定的调用来调用自身,否则它仅使用常规调用.

The loop/2 function takes two arguments: Callbacks, the name of a callback module expected to export specific functions invoked for specific messages, and State, which is opaque to the loop but presumably meaningful to the callback module. The loop is tail recursive and it handles several specific messages by calling specific callback functions, and then handles any other messages by calling handle_info/2 in the callback module. (If you've used the standard behaviors you'll find this approach familiar.) The callback functions return a Next value, and a new state to be passed to the next loop. If Next is stop, we exit the loop, otherwise we check the value of DoChange, which is set to true only for code change messages, and if it's true the loop calls itself with a fully qualified call, otherwise it uses just a regular call.

如前所述,这一切都大大简化了.极少需要编写自己的循环,如果这样做,这里还有一些其他重要的东西未显示,例如您需要处理的系统消息.使用标准行为最好.

As mentioned earlier, this is all greatly simplified. It's extremely rare that you would need to write your own loops, and if you do there are other important things not shown here like system messages that you need to deal with. You are best off using the standard behaviors.

这篇关于在Erlang中使用完全限定的函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆