gpt4 book ai didi

macros - Elixir 中的宏扩展 : how to define 2 macros with one using the other?

转载 作者:行者123 更新时间:2023-12-04 03:36:58 24 4
gpt4 key购买 nike

我正在试验 Elixir 中的宏。因此,我将要展示的代码当然应该用简单的函数来完成,但是……我正在试验!

我想定义 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")

这是编译错误:
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

我(错误)理解事物的方式:
  • 通过要求 MyMacros,模块 MyModule 应该知道这两个宏的存在。因此我应该能够使用任何宏。
  • 在 MyModule 中展开 print_hashes_around 时,编译器应该会发现 print_expr 也是一个宏。因此,应该发生另一个扩展。
  • 似乎发生的是第二次扩展没有发生。因此编译器会寻找一个不存在的函数定义。

  • 我对吗 ?

    正如 slack 中所建议的,前缀 print_exprMyMacros.修复它。我还是不明白为什么。 MyModule需要 MyMacros所以这两个宏都应该是已知的和可扩展的......当我查看 unless 的定义时, 它使用 if ,而不是 Kernel.if .

    最佳答案

    By requiring MyMacros, the module MyModule should know the existence of both macros. Therefore I should be able to use any macros.



    误会就在这里。 :) 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

    关于macros - Elixir 中的宏扩展 : how to define 2 macros with one using the other?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31893989/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com