I have a quoted expression such as this one:
ast = quote do
IO.puts x
end
And I wish to inject a variable into the expression so that x has a value, and the expression won't raise a CompileError
due to x
being undefined when evaluated like so:
Code.eval_quoted ast, [x: "Hello, world!"]
This AST is passed to me, and I cannot change the code it is generated with. I can modify the AST after I've been passed it though.
I thought to do this I could transform the AST to resemble this quoted expression:
ast = quote do
x = var!(x)
IO.puts x
end
After attempting this my AST looks like so:
{:__block__, [],
[{:=, [],
[{:x, [], Elixir}, {:var!, [context: Check.Runner], [{:x, [], Elixir}]}]},
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
[{:x, [], Check.RunnerTest}]}]}
This doesn't work. I thought that this might be due to having an incorrect value for the context of var!
.
Resolution: I now realise that the variables were in the incorrect scope, and I need an AST like this:
{:__block__, [],
[{:=, [],
[{:x, [], Check.RunnerTest},
{:var!, [context: Check.Runner], [{:x, [], Check.Runner}]}]},
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
[{:x, [], Check.RunnerTest}]}]}
Your code should just work. In fact, you have written:
ast = quote do
x = var!(x)
IO.puts x
end
But you showed the AST for some other code, one where you assigned 1
to var!(x)
. In other words, there is nothing wrong with the code above.