【发布时间】:2015-12-02 05:34:18
【问题描述】:
我有一个引用的表达式,比如这个:
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}]}]}
【问题讨论】:
标签: macros metaprogramming elixir hygiene