如何根据 elixir 的属性定义函数?
How to define functions based on attribute to elixir?
假设我有一个模块 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
。我怎样才能实现所需的功能?
您需要将 unquote: false
传递给 Definer.__using__/1
中的 quote
才能将 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
碎片.
假设我有一个模块 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
。我怎样才能实现所需的功能?
您需要将 unquote: false
传递给 Definer.__using__/1
中的 quote
才能将 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
碎片.