我在elixir中试验Macros.因此,我即将展示的代码当然应该用简单的函数完成,但是......我正在试验!
我想定义2个宏(A和B)并使A使用B来试验宏扩展.当我使用A时,我收到一个编译错误,说明函数 B 未定义.
这是代码:
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")
Run Code Online (Sandbox Code Playgroud)
这是编译错误:
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
Run Code Online (Sandbox Code Playgroud)
我(错)理解事物的方式:
我对吗 ?
至于建议在农闲,前缀print_expr与MyMacros.修复它.我还是不明白为什么.MyModule需要MyMacros这样两个宏都应该是已知的并且可以扩展......当我看到unless它的定义时,它会使用if,而不是Kernel.if.
Jos*_*lim 12
通过要求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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1000 次 |
| 最近记录: |