macros - Elixir:在定义它的同一模块的主体中​​使用宏

标签 macros metaprogramming elixir

这是常见的 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/

相关文章:

design-patterns - 在 Clojure 的宏中声明设计模式

maps - 如何在 Elixir 中连接两个 map

Elixir 和字符串中的多个替换字符

objective-c - 多少()宏 objective-c

c++ - 如何从作为模板参数传递的类中获取静态模板方法的地址

必须仅包含在调试版本中的源文件的条件编译

ruby - 如何在运行时在 Ruby 中向现有对象实例添加方法?

functional-programming - 在 Elixir 中编写函数 "once"

c++ - 宏调用中的 #ifdef 适用于 gcc 但不适用于 msvc

macros - 如何使用先前的定义重新定义宏