这是常见的 Elixir :
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
end
defmodule Buzz do
require Fizz
Fizz.asdf
end
但是,尽管您可以在同一上下文中引用宏,例如:
defmodule Fizz do
# ...
defmacro asdf_qwer, do: asdf && IO.puts("qwer")
end
...您无法在定义宏的同一模块的主体中引用宏:
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
asdf
end
这会引发未定义的函数asdf/0
。
这个“问题”有解决方法吗?有时我可能想使用宏从我正在处理的模块中删除一些样板文件,并且该宏的功能可能足够具体,无需将其放入另一个模块中。
最佳答案
我们在这里收到未定义函数
错误的原因是在编译时,asdf
宏还不存在。
所以我们需要在编译完成之前通知编译器需要执行一个额外的步骤。
一个选项是 @after_compile模块回调属性允许您在编译后调用一些代码以执行最后的代码生成。
例如:
defmodule M do
@after_compile __MODULE__
def __after_compile__(env, _bytecode) do
IO.inspect env
end
end
另一种选择是将宏放入 Fizz.Macros
模块中。
关于macros - Elixir:在定义它的同一模块的主体中使用宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38662970/