【问题标题】:Elixir: use macro in the body of same module that defined itElixir:在定义它的同一模块的主体中​​使用宏
【发布时间】:2016-12-04 09:59:15
【问题描述】:

这是常见的灵丹妙药:

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

这引发了undefined function asdf/0

这个“问题”有解决方法吗?有时我可能想使用宏从我正在处理的模块中删除一些样板,并且该宏的功能可能足够具体,以至于不能将其放入另一个模块中。

【问题讨论】:

    标签: macros metaprogramming elixir


    【解决方案1】:

    我们在这里收到undefined function 错误的原因是因为在编译时,asdf 宏还不存在。

    所以我们需要在编译完成之前通知编译器需要一个额外的步骤。

    一个选项是@after_compile 模块回调属性,它允许您在编译后调用一些代码以执行最后一点代码生成。

    例如:

    defmodule M do
      @after_compile __MODULE__
    
      def __after_compile__(env, _bytecode) do
        IO.inspect env
      end
    end
    

    另一种选择是将您的宏放在Fizz.Macros 模块中。

    【讨论】:

    • 我看不到 @after_compile 如何帮助在其定义模块中使用宏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 2019-05-27
    相关资源
    最近更新 更多