我想要定义一个宏,这样我就可以向它传递一个do块,并让这个宏创建一个函数来调用这个块,和一个参数。我遇到了一个鸡蛋问题,因为下面的代码抱怨没有定义name。
defmodule MyMacro do
defmacro greet(do: block) do
quote do
def hello(name), do: unquote(block)
end
end
end
defmodule Test do
import MyMacro
greet do
IO.puts("Hello, #{name}!")
end
end试图编译此代码将导致:
(CompileError) iex:6: undefined function name/0
(stdlib) lists.erl:1338: :lists.foreach/2
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5据我理解,这甚至在它到达我的宏之前就已经崩溃了,因为长生不老药试图在调用我的宏之前为do块生成AST,但是name是未定义的。
我的目标是能够在编译DSL之后调用Test.hello("world")。这有可能在长生不老药吗?
发布于 2018-06-10 03:14:47
灵丹妙药的宏是卫生学,因此如果在宏的quote中声明变量,调用方将无法使用它。您可以通过用var!包装变量的声明来禁用它。
quote do
def hello(var!(name)), do: unquote(block)
endhttps://stackoverflow.com/questions/50780247
复制相似问题