可能有一些内容会和上一篇重复, 但我认为这对于理解运作原理和 AST 的生成很有帮助. 掌握了这些以后, 你对于自己的宏代码就更有信心了....因此, 在这段代码的展开阶段, Tracer.trace/1会被调用.
我们的宏接受了输入的 AST, 然后必须生成输出的 AST. 之后编译器会简单地用输出的 AST 替换掉对宏的调用....为什么呢?因为宏有两个看似矛盾的性质:
宏也是 Elixir 代码
宏在在最终的字节码生成之前的展开阶段运行
Elixir 代码是如何在被生成之前运行的?它不能....是一样的, 所以当我们调用 get route do ... end 时, 我们实际上是在调用 get(route, do: ...)...理想情况下, 当我们这样做时, 我们不需要关心输入 AST 的内容, 在我们的例子中, 我们只需要在生成的函数中注入函数体, 而不需要关心函数体中实际有什么.
测试这个宏很简单.