Ответ, опубликованный ранее, чрезвычайно сложен.Для этой цели у нас есть Kernel.defdelegate/2
.Кроме того, все еще неясно, как обрабатывать модули с функциями с одинаковыми именами .
defmodule M1, do: def f1, do: 42
defmodule M2, do: def f2(_a1, _a2), do: 42
defmodule Wrapper do
defmacro __using__(modules) do
user_defs =
modules
|> Enum.map(&Macro.expand(&1, __ENV__))
|> Enum.map(&{&1, &1.module_info(:exports)})
for {module, exports} <- user_defs do
for {func, arity} <- exports, func not in ~w|module_info __info__|a do
args = for i <- 0..arity, i > 0,
do: Macro.var(:"arg#{i}", __MODULE__)
quote do
# Use as: unquote("#{func}_#{module}") to resolve dups
defdelegate unquote(func)(unquote_splicing(args)),
to: unquote(module), as: unquote(func)
end
end
end
end
end
defmodule Test, do: use Wrapper, [M1,M2]