Macros 将变量注入到带引号的表达式中

Macros 将变量注入到带引号的表达式中,macros,metaprogramming,elixir,hygiene,Macros,Metaprogramming,Elixir,Hygiene,我引用了这样一句话: ast = quote do IO.puts x end 我希望向表达式中注入一个变量,使x有一个值,并且表达式不会产生CompileError,因为x在这样计算时未定义: Code.eval_quoted ast, [x: "Hello, world!"] 此AST已传递给我,我无法更改生成它的代码。我可以在通过AST后修改它 我想这样做,我可以将AST转换为类似以下引用的表达式: ast = quote do x = var!(x) IO.puts x

我引用了这样一句话:

ast = quote do
  IO.puts x
end
我希望向表达式中注入一个变量,使x有一个值,并且表达式不会产生
CompileError
,因为
x
在这样计算时未定义:

Code.eval_quoted ast, [x: "Hello, world!"]
此AST已传递给我,我无法更改生成它的代码。我可以在通过AST后修改它

我想这样做,我可以将AST转换为类似以下引用的表达式:

ast = quote do
  x = var!(x)
  IO.puts x
end
尝试此操作后,我的AST看起来是这样的:

{:__block__, [],
[{:=, [],
  [{:x, [], Elixir}, {:var!, [context: Check.Runner], [{:x, [], Elixir}]}]},
  {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
  [{:x, [], Check.RunnerTest}]}]}
这不管用。我认为这可能是因为
var的上下文中有一个不正确的值

解决方案:我现在意识到变量在不正确的范围内,我需要这样的AST:

{:__block__, [],
[{:=, [],
  [{:x, [], Check.RunnerTest},
    {:var!, [context: Check.Runner], [{:x, [], Check.Runner}]}]},
  {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
  [{:x, [], Check.RunnerTest}]}]}

您的代码应该可以正常工作。事实上,你写过:

ast = quote do
  x = var!(x)
  IO.puts x
end

但是您显示了一些其他代码的AST,其中您将
1
分配给
var!(x) 
。换句话说,上面的代码没有问题。

啊,我粘贴了错误的代码。在阅读了下面的评论后,我意识到由于设置了不正确的上下文,我将变量放在了不正确的范围内。我已经更新了上面的问题。既然您已经更新了问题,那么问题本身就错了(示例确实有效),并且这个答案有些错误派普。一切都有点乱。也许最好现在就走开!