Ale*_*kin 3 macros metaprogramming elixir
我在模块中生成一些函数:
defmodule M do
funs = [do_it: [:arg1, :arg2]]
Enum.each(funs, fn {name, args} ->
args = Enum.map(args, & {&1, [], Elixir})
def unquote(name)(unquote(args)),
do: IO.inspect(unquote(args))
end)
end
Run Code Online (Sandbox Code Playgroud)
问题是生成的函数显然接受一个参数,即大小为2的列表:
? M.__info__(:functions)
#? [do_it: 1]
Run Code Online (Sandbox Code Playgroud)
目标是动态声明接受两个参数的函数.在ruby术语中,它将是unsplat参数列表.
是否有可能在没有模式匹配生成的AST {:do_it, blah, [[ list of arguments ]]}
并手动展平列表的情况下完成此操作?
您可以使用列表Kernel.SpecialForms.unquote_splicing/1
中的"拼接" args
:
defmodule M do
funs = [do_it: [:arg1, :arg2], do_it: [:arg1, :arg2, :arg3]]
Enum.each(funs, fn {name, args} ->
def unquote(name)(unquote_splicing(args)), do: :ok
end)
end
Run Code Online (Sandbox Code Playgroud)
iex(1)> M.__info__(:functions)
[do_it: 2, do_it: 3]
Run Code Online (Sandbox Code Playgroud)