Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 如何获取未引用/扩展的参数&x2019;宏中的s值_Macros_Elixir_Metaprogramming - Fatal编程技术网

Macros 如何获取未引用/扩展的参数&x2019;宏中的s值

Macros 如何获取未引用/扩展的参数&x2019;宏中的s值,macros,elixir,metaprogramming,Macros,Elixir,Metaprogramming,我需要在调用a.target defmodule A do defmacro target(param) do IO.inspect param, label: "Inside a macro" end end defmodule B do @attr 42 require A A.target(@attr) end 我当然有 Inside a macro: {:@, [line: 10], [{:attr, [line: 10], nil}]} 打印,因为此时

我需要在调用
a.target

defmodule A do
  defmacro target(param) do
    IO.inspect param, label: "Inside a macro"
  end
end

defmodule B do
  @attr 42
  require A
  A.target(@attr)
end
我当然有

Inside a macro: {:@, [line: 10], [{:attr, [line: 10], nil}]}
打印,因为此时正在构建AST,并且
A.target/1
不负责扩展其参数。我发现我可以访问参数的值,而不是在
quote do
块中访问它的AST:

defmodule A do
  defmacro target(param) do
    quote do: IO.inspect uquote(param), label: "unquote"
  end
end
问题是我需要提前扩展值。我所尝试的:

  • var
  • 宏。展开
  • code.eval的任何变化

所以,我的问题是:是否可以在宏体的第一行强制展开宏参数

我不相信您可以。在宏的引号块之外,@attr没有值。这只是一个引用的表达。模块B尚未编译。您只能在A的quote块内访问@attr,因为它是在B的上下文中执行的。

这不是您想要的吗

defmodule A do
  defmacro target(param) do
    quote do
      IO.inspect unquote(param), label: "Inside a macro"
    end
  end
end

defmodule B do
  @attr 42
  require A
  A.target(@attr)
end
宏接收引用的参数。要获得实际值,必须将其取消报价。只能在quote块内取消引用参数


当一个宏返回一个带引号的表达式时,它被插入调用模块并运行,这样就可以知道
IO.inspect…
正在
B
模块内运行。

问题有点晚了;编写长生不老药宏的新手

我不建议这样编程,但这是一个有趣的练习

看起来您的问题是关于使用常量@attr

这是这个问题的一个主要痛点


这绝对是一个听起来合理的黑客行为,我的第一个猜测就是这个。另一方面,应该可以推迟AST的扩展,以允许(例如)迭代传递给宏的参数/基于某些尚未扩展的配置生成生成的AST。可以,但只有在宏的quote块内取消quote时,AST才有效。你能解释一下你想做什么吗?我试图向库提供一个pull请求,该请求通过一组宏传递无引号的值。我只是试图通过不接触现有代码来最小化这个PR的大小,但这似乎是不可能的。