gpt4 book ai didi

Erlang:有没有办法从我的模块中导出其他模块的导出?

转载 作者:行者123 更新时间:2023-12-02 01:47:31 25 4
gpt4 key购买 nike

我正在为 webmachine 编写一些资源,它们共享许多相同的功能。所以我想知道是否可以在单独的模块中编写常用函数,然后以某种方式包含它,并让资源自动导出其导出(而不必从每个资源显式导出它们)。

最佳答案

我们有一个包装器模块,它实现所有 Webgear 回调,并将它们传输到真正的实现模块(如果在那里实现)。该模块可以对某些部分有特殊的实现,甚至可以在使用它的模块中启用新的回调。基本上,该模块是所有其他资源的包装资源。

首先,您的调度 map 如下所示:

[{"/some/path", webgear_wrapper, {actual_resource, ["Some", extra, "Args"]}}].

为此,您需要发现实际实现模块实现了哪些回调:

-record(context, {module, context, exports}).

init({Mod, Args}) ->
{ok, Context} = Mod:init(Args),
{ok, #context{module = Mod, context = Context, exports = exports(Mod)}}.

exports(Mod) ->
dict:from_list(Mod:module_info(exports)).

这将初始化一个基本的 Webgear 资源,该资源包含有关其状态中的真实回调模块的信息。

然后,对于包装器资源的每个回调(如果您希望实现模块能够使用该资源,您必须实现该资源),您将看到该函数是否已实现并在那里处理它,使用这个函数:

call(#context{module = Mod, context = Cxt, exports = Exports},
Func, Req, Default) ->
case dict:is_key(Func, Exports) of
true -> Mod:Func(Req, Cxt);
false -> {Default, Req, Cxt}
end.

例如,call/4 函数在包装器模块中的使用方式如下:

malformed_request(Req, Cxt) ->
% false here is the default value to return if the callback is missing
{Res, NewReq, NewCxt} = call(Cxt, malformed_request, Req, false),
% Now we must update the state accordingly
{Res, NewReq, Cxt#context{context = NewCxt}}.

这在我们的项目中效果很好,其中所有资源共享一些通用逻辑(在这样的包装器模块中实现)。虽然还没有对性能进行太多基准测试,但开销应该相当小(一次字典查找和一次额外的模块调用,再加上一些记录整理)。

关于Erlang:有没有办法从我的模块中导出其他模块的导出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5051453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com