Quote and unquote
Quoting
quote sempre retorna uma tupla de 3 posição:
- nome da função
- metadados
- argumentos da função
quote do: sum(1, 2, 3)
quote do: 1 + 2
quote do: %{1 => 2}
# mas no caso de variável, a última posição não é o argumento
quote do: x
quote do: sum(1, 2 + 3, 4)
Macro.to_string(quote do: sum(1, 2 + 3, 4))
Normalmente o quote retorna o seguinte formato:
{atom | tuple, list, list | atom}
1º) é um atom ou outra tupla nesse formato
2º) é uma keywork list com metadados como números e contextos
3º) é uma lista de argumentos quando o primeiro for uma função, ou um atom quando o primeiro for uma variável
Existem literais que o quote retorna o próprio elemento:
IO.puts("Atoms")
quote do: :sum
IO.puts("Numbers")
quote do: 1.0
IO.puts("Lists")
quote do: [1, 2]
IO.puts("Strings")
quote do: "strings"
IO.puts("Tuples with two elements")
quote do: {1, 2}
quote do: String.upcase("foo")
quote do: if(true, do: :this, else: :that)
quote do: if(true) do
:this
else
:that
end
quote do:
(if true do
:this
else
:that
end)
Unquoting
number = 13
Macro.to_string(quote do: 11 + number)
number = 13
Macro.to_string(quote do: 11 + unquote(number))
fun = :hello
Macro.to_string(quote do: unquote(fun)(:world))
inner = [3, 4, 5]
Macro.to_string(quote do: [1, 2, unquote_splicing(inner), 6])
quote do: %{1 => 2}
map = %{hello: :world}
Macro.escape(map)
map = %{hello: :world}
quote do: map
OBS: alguns elementos não podem ser explicitamente convertidos para quote:
pid = spawn(fn -> 1 end)
Macro.escape(pid)
###
defmodule X do
def f do
10
end
end
Macro.escape(X.f())