将变量注入引用表达式
Injecting variables into a quoted expression
我有一个引用表达式,例如这个:
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)
。也就是说,上面的代码没有任何问题。
我有一个引用表达式,例如这个:
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)
。也就是说,上面的代码没有任何问题。