Reputation: 4906
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?
Upvotes: 3
Views: 941
Reputation: 51349
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
Upvotes: 4
Reputation: 129
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
Upvotes: 4