Macros elixir中的宏扩展:如何定义两个宏,其中一个使用另一个?
我正在用长生不老药试验宏。因此,我将要展示的代码当然应该使用简单的函数来完成,但是。。我在试验 我想定义两个宏(A和B),并使用B来试验宏扩展。 当我使用A时,我得到一个编译错误,表示函数B是未定义的 代码如下:Macros elixir中的宏扩展:如何定义两个宏,其中一个使用另一个?,macros,elixir,Macros,Elixir,我正在用长生不老药试验宏。因此,我将要展示的代码当然应该使用简单的函数来完成,但是。。我在试验 我想定义两个宏(A和B),并使用B来试验宏扩展。 当我使用A时,我得到一个编译错误,表示函数B是未定义的 代码如下: defmodule MyMacros do defmacro print_expr(expr) do quote do IO.puts(unquote(expr)) end end defmacro print_hashes_around(ex
defmodule MyMacros do
defmacro print_expr(expr) do
quote do
IO.puts(unquote(expr))
end
end
defmacro print_hashes_around(expr) do
quote do
IO.puts "###"
print_expr(unquote(expr))
IO.puts "###"
end
end
end
defmodule MyModule do
require MyMacros
def my_print(expr) do
MyMacros.print_hashes_around(expr)
end
end
MyModule.my_print("hello world")
下面是编译错误:
macro_test.exs:17: warning: redefining module MyModule
** (CompileError) macro_test.exs:21: function print_expr/1 undefined
(stdlib) lists.erl:1336: :lists.foreach/2
macro_test.exs:17: (file)
(elixir) lib/code.ex:307: Code.require_file/2
我(错误地)理解事物的方式:
print\u expr
前面加上MyMacros。
修复了它。我还是不明白为什么MyModule
需要MyMacros
,因此这两个宏都应该是已知的并且可以扩展的。。。当我查看的定义时,除非,否则它使用if
,而不是Kernel.if
通过要求使用MyMacros,模块MyModule应该知道这两个宏的存在。因此,我应该能够使用任何宏
误解就在这里require
仅使模块可供编译器使用,而不导入模块函数。如果您使用import MyModule
,那么它就可以工作了
但是,最好通过在模块名称前加前缀来解决此问题,因为这样可以允许使用代码的开发人员显式使用宏(使用require
)或导入宏
另一种选择是避免像这样的多个宏调用:
defmodule MyMacros do
defmacro print_expr(expr) do
quoted_print_expr(expr)
end
defmacro print_hashes_around(expr) do
quote do
IO.puts "###"
unquote(quoted_print_expr(expr))
IO.puts "###"
end
end
defp quoted_print_expr(expr) do
quote do
IO.puts(unquote(expr))
end
end
end
谢谢José,能从语言创造者那里得到答案真是太棒了!