Erlang:使用新功能“扩展”现有模块

时间:2011-06-30 05:00:34

标签: erlang

我目前正在编写一些与列表相关的函数,我可以重用它们。

我的问题是:

是否有任何组织此类功能的惯例或最佳做法?

为了构建这个问题,我希望“扩展”现有的列表模块,以便我按以下方式调用我的新函数:lists:my_funcion()。目前我有lists_extensions:my_function()。反正有吗?

我读到了关于erlang包的内容,它们本质上是Erlang中的命名空间。是否可以使用新的Lists函数为列表定义新的命名空间?

请注意,我不打算分叉和更改标准列表模块,而是要找到一种在新模块中定义新函数的方法,也称为Lists,但是通过使用某种类型的命名空间方案来避免后续的命名冲突。 / p>

任何建议或参考将不胜感激。

干杯。

4 个答案:

答案 0 :(得分:4)

  

为了构建这个问题,我希望“扩展”现有的列表模块,以便我按以下方式调用我的新函数:lists:my_funcion()。目前我有lists_extensions:my_function()。反正有吗?

不,据我所知。

  

我读到了关于erlang包的内容,它们本质上是Erlang中的命名空间。是否可以使用新的Lists函数为列表定义新的命名空间?

他们是experimental and not generally used。你可以在一个不同的命名空间中有一个名为lists的模块,但是你可能无法从这个命名空间中的标准模块调用函数。

答案 1 :(得分:1)

我告诉您为什么使用lists:your_function()并改为使用lists_extension:your_function()

但是,我明白为什么你想要 lists:your_function/N

  • your_function的作者使用起来比较容易,因为在使用your_function(...)时他需要[]当另一个Erlang程序员 - 谁知道stdlb - 读取此代码时,他将不知道它的作用。这很令人困惑。
  • 它看起来比lists_extension:your_function/N更简洁。 这是一个品味问题。

答案 2 :(得分:1)

我认为这种方法适用于任何发行版:

您可以创建一个应用程序,自动重写正在运行的分发版的核心erlang模块。将自定义函数附加到核心模块并重新编译它们,然后再编译并运行调用自定义函数的应用程序。这不需要自定义分发。只需仔细规划和使用文件工具和BIF进行编译和加载。 *您希望确保每次都不附加功能。重写文件后,除非用户稍后替换该文件,否则它将是永久性的。可以使用module_info检查确认您的自定义函数是否存在,以决定是否需要运行扩展编写器。

伪示例:

lists_funs() -> ["myFun() -> <<"things to do">>."].
extend_lists() -> 
   {ok, Io} = file:open(?LISTS_MODULE_PATH, [append]),
   lists:foreach(fun(Fun) -> io:format(Io,"~s~n",[Fun]) end, lists_funs()),
   file:close(Io),
   c(?LISTS_MODULE_PATH).

*如果编译器失败,您可能希望保留原始模块的副本,如果您在功能列表中出错并且在任何时候都需要用作源,则不必做任何重的事情。重写模块以使用更多功能扩展它。 *您可以使用list_extension模块来保留函数的所有逻辑,并使用funName(Args) -> lists_extension:funName(Args).将函数传递给此函数中的列表 *您还可以创建一个覆盖系统来搜索现有函数并以类似的方式重写它们,但它更复杂。 我确信有很多方法可以改进和优化这种方法。我使用类似的东西在运行时更新我自己的一些模块,所以我没有看到它也不适用于核心模块。

答案 3 :(得分:-1)

我想你想要做的是从list模块中访问你的一些函数。您希望将常用代码转换为库是件好事。

这样做的一种方法是很好地测试你的函数,如果它们没问题,你复制函数,将它们粘贴到lists.erl模块中(警告:确保你不要覆盖现有的函数,只需粘贴在文件的末尾)。此文件位于路径 $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/src/lists.erl 中。确保在列表模块(-export([your_function/1,.....]))中导出的函数中添加函数,以便可以从其他模块访问它们。保存文件。

完成此操作后,我们需要重新编译list模块。您可以使用EmakeFile。该文件的内容如下:

{"src/*", [verbose,report,strict_record_tests,warn_obsolete_guard,{outdir, "ebin"}]}.

将该文本复制到名为 EmakeFile 的文件中。将此文件放在路径中: $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/EmakeFile

完成此操作后,继续打开一个erlang shell并让其 pwd() ,当前工作目录为EmakeFile所在的路径,即 {{1 }}

在shell中调用函数: $ERLANG_INSTALLATION_FOLDER/lib/stdlib-{$VERSION}/ ,您将看到重新编译模块列表。关闭shell。

一旦你打开一个新的erlang shell,并假设你在lists模块中导出了你的函数,它们将按照你想要的方式运行,就在list模块中。 Erlang是开源的,允许我们添加功能,重新编译和重新加载库。这应该做你想要的,成功。