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的大小,但这似乎是不可能的。