Inserting a dynamic variable using meta programming

I am trying to insert a dynamically named variable using the following code:


defmodule Revive do
  defmacro revive(key, val) do
    quote do
      var!(unquote(key)) = unquote(val)
    end
  end
end

require Revive

Revive.revive(:user, "Aku")

Error:

** (ArgumentError) expected a variable to be given to var!, got: :user
    (elixir) lib/kernel.ex:3496: Kernel."MACRO-var!"/3
    (elixir) expanding macro: Kernel.var!/1
    iex:6: (file)
    expanding macro: Revive.revive/2
    iex:6: (file)

Is this even possible in Elixir?

You want a variable? Then pass a variable, and not an atom:

iex(1)> defmodule Revive do
...(1)>   defmacro revive(key, val) do
...(1)>     quote do
...(1)>       var!(unquote(key)) = unquote(val)
...(1)>     end
...(1)>   end
...(1)> end
{:module, Revive,
 <<70, 79, 82, 49, 0, 0, 4, 132, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 140,
   0, 0, 0, 15, 13, 69, 108, 105, 120, 105, 114, 46, 82, 101, 118, 105, 118,
   101, 8, 95, 95, 105, 110, 102, 111, 95, 95, ...>>, {:revive, 2}}
iex(2)> require Revive
Revive
iex(3)> user          
** (CompileError) iex:4: undefined function user/0

iex(3)> Revive.revive(user, "Aku")
"Aku"
iex(4)> user
"Aku"
5 Likes