Hello!
# Functions are easy!
m = %{}
put_deep(m, [:foo, :bar, :baz], 1)
%{foo: %{bar: %{baz: 1}}}
# Macros are hard.
m = %{}
put_deep(m.foo.bar.baz, 1)
# how??
Here’s my macro…
defmacro put_deep(path, value) do
{_node, {var, keys}} = Macro.postwalk(path, nil, fn node, acc ->
acc = case {node, acc} do
{{var, _, nil}, nil} -> {var, []}
{key, {var, keys}} when is_atom(key) -> {var, [key | keys]}
{junk, acc} when is_tuple(junk) -> acc
end
{node, acc}
end)
keys = Enum.reverse(keys)
IO.inspect(var)
IO.inspect(keys)
quote location: :keep do
put_deep(unquote(var), unquote(keys), unquote(value))
end
end
The IO.inspect()
calls produces:
:m
[:foo, :bar, :baz]
So I have the variable name as a symbol, but I don’t know how to access that variable from the macro.
I’ve tried tons of combinations of Kernal.var!
, Macro.var
, and Macro.escape
.
Thanks for the help!