nic*_*oga 5 macros metaprogramming elixir
这是常见的灵药:
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
end
defmodule Buzz do
require Fizz
Fizz.asdf
end
Run Code Online (Sandbox Code Playgroud)
但是,尽管您可以在相同的上下文中引用宏,例如:
defmodule Fizz do
# ...
defmacro asdf_qwer, do: asdf && IO.puts("qwer")
end
Run Code Online (Sandbox Code Playgroud)
...您不能在定义它们的同一模块的主体中引用宏:
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
asdf
end
Run Code Online (Sandbox Code Playgroud)
这引起了提升undefined function asdf/0.
这个"问题"有解决方法吗?有时我可能想使用宏从我正在处理的模块中删除一些样板,并且该宏的功能可能足够具体,不会将其放在另一个模块中.
小智 1
我们在这里收到错误的原因undefined function是因为在编译时,asdf宏还不存在。
因此,我们需要在编译完成之前通知编译器需要执行额外的步骤。
一个选项是@after_compile模块回调属性,它允许您在编译后调用一些代码,以执行最后的代码生成。
例如:
defmodule M do
@after_compile __MODULE__
def __after_compile__(env, _bytecode) do
IO.inspect env
end
end
Run Code Online (Sandbox Code Playgroud)
另一种选择是将宏放入Fizz.Macros模块中。