Elixir重命名并包装Erlang模块?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elixir重命名并包装Erlang模块?相关的知识,希望对你有一定的参考价值。
是否可以重命名现有的Erlang模块?我想在Elixir项目(断言库)中使用的几个Erlang模块中有一些代码。
我不想将所有Erlang模块转换为Elixir,因为它们已完成,但我想重命名它们,并可能为它们添加其他功能。这两个模块都只是函数集合,它们不实现行为或做任何不寻常的事情。
我希望能够使用现有的Erlang模块:
-module(foo_erl).
-export([some_fun/1]).
some_fun(Arg) ->
ok.
并编写一个Elixir模块来扩展Erlang:
defmodule ExFoo do
somehow_extends_erlang_module :foo_erl
another_fun(arg) do
:ok
end
end
然后能够使用Erlang模块中定义的函数:
iex(1)> ExFoo.some_fun(:arg) #=> :ok
Elixir有可能吗?如果是这样,我该怎么做呢?
答案
一般来说,我们建议避免包装Erlang模块。如果你想以自动方式包装许多模块,velimir的帖子就在现场。
如果你有一次性的情况,你肯定想要包装一个Erlang模块,我建议只使用defdelegate
:
defmodule MyLists do
defdelegate [flatten(list), map(fun, list)], to: :lists
end
另一答案
这是我可以提出的第一件事。我百分百肯定它可以以更优雅的方式解决。我稍后会回到这里,因为我还不是Elixir的大师。
defmodule Wrapper do
defmacro __using__(module) do
exports = module.module_info[:exports] -- [module_info: 0, module_info: 1]
for {func_name, arity} <- exports do
args = make_args(arity)
quote do
def unquote(func_name)(unquote_splicing(args)) do
unquote(module).unquote(func_name)(unquote_splicing(args))
end
end
end
end
defp make_args(0), do: []
defp make_args(arity) do
Enum.map 1..arity, &(Macro.var :"arg#{&1}", __MODULE__)
end
end
defmodule WrapperTest do
use ExUnit.Case, async: true
use Wrapper, :lists
test "max function works properly" do
assert (max [1, 2]) == 2
end
end
以上是关于Elixir重命名并包装Erlang模块?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Elixir或Erlang中在运行时动态创建和加载模块?
在 Elixir 或 Erlang 中,如何在运行时动态创建和加载模块?