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