我目前正在学习/阅读元编程灵药 我设法生成一个函数,使用宏来设置它的名称:
defmodule MyMacros do
defmacro fun_gen(name) do
atom_name = elem(name, 0)
str_name = atom_name |> to_string
quote do
def unquote(name) do
IO.puts unquote(str_name)
end
end
end
end
defmodule My do
require MyMacros
MyMacros.fun_gen(bar)
end
结果:
iex(1)> My.bar
bar
:ok
所以这很棒:)但我想知道是否可以使用Enum.each或类似的东西生成几个函数:
defmodule MyMacros do
defmacro fun_gen(name) do
atom_name = elem(name, 0)
str_name = atom_name |> to_string
quote do
def unquote(name) do
IO.puts unquote(str_name)
end
end
end
end
defmodule My do
require MyMacros
loop (~w(foo bar baz) do
MyMacros.fun_gen(item)
end
end
有没有一种循环方式来生成源代码? 谢谢!
答案 0 :(得分:3)
你可以在不使用宏的情况下完成它:
defmodule My do
@methods ~w|one two three|a
for method <- @methods do
def unquote(method)() do
IO.puts unquote(method)
end
end
end
产生
iex> My.one
one
iex> My.two
two
或者使用宏:
defmodule MyMacros do
defmacro gen_funs(names) do
for name <- names do
quote do
def unquote(name)() do
IO.puts unquote(name)
end
end
end
end
end
defmodule My2 do
require MyMacros
MyMacros.gen_funs([:one, :two, :three])
end
产生
iex> My2.one
one
iex> My2.two
two
注意:我们将列表直接传递给gen_funs
而不是sigil或包含列表的变量。我们必须这样做,因为宏接收引用的参数。这就是为什么你必须在宏中而不是使用宏的模块中进行循环。