This is a bit of an odd question but I am curious. I can start up a new iex
session, assign a variable, and look at the bindings in the current scope:
iex(1)> x = 1
1
iex(2)> binding()
[x: 1]
Which is neat. Now I can create a quoted expression that assigns a value to a different variable:
iex(3)> expr = quote do var!(y) = 2 end
{:=, [], [{:var!, [context: Elixir, import: Kernel], [{:y, [], Elixir}]}, 2]}
and I can see what the result of evaluating that expression against the current binding might be:
iex(4)> Code.eval_quoted(expr, binding())
{2,
[expr: {:=, [],
[{:var!, [context: Elixir, import: Kernel], [{:y, [], Elixir}]}, 2]}, x: 1,
y: 2]}
So we see that if I evaluated the expression starting with a set of bindings just like the bindings in my current context, that the result would have a value of 2 and the new set of bindings would include the variable y with a value of 2.
However if I actually check my bindings after the eval call, I see:
iex(5)> binding()
[expr: {:=, [],
[{:var!, [context: Elixir, import: Kernel], [{:y, [], Elixir}]}, 2]}, x: 1]
So evaluating the quoted expression didn’t actually change the current bindings (just showed me what could have happened). This makes total sense since I created a copy of my current bindings (an immutable object) and passed it along.
Is there any way to evaluate the quoted expression (i.e. expr
) in the current context so that it actually changes the current set of bindings?