我们说我有一个模块Silent
和Definer
。我想基于其属性为Silent
定义几个函数。让我解释一下:
defmodule Silent do
@function_names [:a, :b, :c]
use Definer
end
defmodule Definer do
defmacro __using__(_) do
quote do
Enum.each(@function_names, fn(n) ->
def unquote(n)() do # line 5
IO.puts "a new method is here!"
end
end)
end
end
end
但这种方法实际上并不起作用,因为我有undefined function n/0 on line 5
。如何实现所需的功能?
答案 0 :(得分:1)
您需要将unquote: false
传递到quote
中的Definer.__using__/1
才能在unquote
内注入quote
个片段。
defmodule Definer do
defmacro __using__(_) do
quote unquote: false do
Enum.each(@function_names, fn(n) ->
def unquote(n)() do # line 5
IO.puts "a new method is here!"
end
end)
end
end
end
defmodule Silent do
@function_names [:a, :b, :c]
use Definer
end
Silent.a
Silent.b
Silent.c
打印
a new method is here!
a new method is here!
a new method is here!
Kernel.SpecialForms.quote/2 docs中详细记录了类似的案例,如果您想要将一些变量注入bind_quoted
并创建quote
,则会提及如何使用unquote
片段。