Arguments passed to macro are passed as quoted (meaning they are not evaluated). Since def
is a macro, the do
block is quoted, and therefore, you can call unquote
from it, just like you can from any other argument passed to the macro. The same holds for an invocation of any other macro, including your own:
iex> defmodule Foo do
defmacro bar(x) do
IO.inspect x
nil
end
end
iex> require Foo
iex> Foo.bar(unquote(x))
{:unquote, [line: 3], [{:x, [line: 3], nil}]}
iex> Foo.bar do unquote(y) end
[do: {:unquote, [line: 4], [{:y, [line: 4], nil}]}]