Elixir rename and wrap Erlang module?

[亡魂溺海] 提交于 2019-12-07 16:48:44

问题


Is it possible to rename an existing Erlang module? I have some code in several Erlang modules that I want to use in an Elixir project (assertion library).

I don't want to convert all the Erlang modules to Elixir as they are complete, but I want to rename them, and possible add additional functions to them. Both modules are simply collections of functions, they don't implement behaviors or do anything unusual.

I want to be able to take an existing Erlang module:

-module(foo_erl).

-export([some_fun/1]).

some_fun(Arg) ->
  ok.

And write an Elixir module to extend the Erlang one:

defmodule ExFoo do
   somehow_extends_erlang_module :foo_erl

   another_fun(arg) do
     :ok
   end
end

And then be able to use the functions defined in the Erlang module:

iex(1)> ExFoo.some_fun(:arg) #=> :ok

Is this possible in Elixir? If so, how would I go about doing this?


回答1:


In general, we suggest to avoid wrapping Erlang modules. In case you want to wrap many modules in an automatic fashion, velimir's post is right on the spot.

If you have one-off case though, where you definitely want to wrap an Erlang module, I would suggest to simply use defdelegate:

defmodule MyLists do
  defdelegate [flatten(list), map(fun, list)], to: :lists
end



回答2:


Here's the first thing that I can suggest. I'm 100% sure that it could be solved in a more elegant way. I'll back to this later since I'm not an Elixir guru yet.

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


来源:https://stackoverflow.com/questions/25694387/elixir-rename-and-wrap-erlang-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!