Elixir 中的元编程

Metaprogramming in Elixir

defmodule BBB do
  IO.puts "BBB"
  defmacro hh do
    IO.puts "hh in BBB"
  end
end

defmodule AAA do
  IO.puts "AAA"
  require BBB
  BBB.hh
end

为什么输出是:

BBB
hh in BBB
AAA

我对 Elixir 的编译过程感到很困惑。

我假设您预计 hh in BBB 会在 AAA 之后。之所以相反,是因为当 AAA 被编译时,宏 hh 首先被展开。由于 hh 直接打印一个值而不是 return 打印引用的片段,因此它在执行 AAA 模块中的任何表达式之前执行。

如果将 hh 更改为普通 def 而不是 defmacro:

def hh do
  IO.puts "hh in BBB"
end

或者您将 defmacro hh 更改为 return 引用的 AST,它打印字符串:

defmacro hh do
  quote do
    IO.puts "hh in BBB"
  end
end

输出将首先是 AAA,然后是 hh in BBB