3

我有一个引用的表达式,例如:

ast = quote do
  IO.puts x
end

CompileError我希望在表达式中注入一个变量,以便 x 有一个值,并且当像这样评估时,由于 x未定义,表达式不会引发 a :

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}]}]}
4

1 回答 1

2

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

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

但是您展示了其他代码的 AST,即您分配1var!(x). 换句话说,上面的代码没有任何问题。

于 2015-09-06T17:58:16.973 回答