Nehmen wir das Beispiel ein wenig vereinfachen:
for fn_name <- [:foo, :bar, :baz] do
defmacro unquote(fn_name)(do: inner) do
fn_name = unquote(fn_name) # <--- Why?
quote do
{unquote(fn_name), unquote(inner)}
end
end
end
Im Beispiel oben, weil Zitat ist Zurückgeben eines Tupels mit zwei nicht angeklagten Elementen entspricht dies:
for fn_name <- [:foo, :bar, :baz] do
defmacro unquote(fn_name)(do: inner) do
fn_name = unquote(fn_name) # <--- Why?
{fn_name, inner}
end
end
Jetzt ist es einfacher zu verstehen, was passiert, wenn Sie nicht unquote(fn_name)
vorher: die Variable fn_name
wäre einfach nicht innerhalb der Makrodefinition existieren. Denken Sie daran, dass alle def
s (def, defp, defmacro usw.) einen neuen Variablenbereich starten. Wenn Sie also fn_name inside verwenden möchten, müssen Sie dies irgendwie definieren.
Die andere Eigenschaft, die wir in diesem Code sehen, ist, dass Elixir nicht mehr quittiert, wenn es eine quote
sieht. In dem obigen Zitat wird unquote
nicht entkoppelt, wenn das Makro definiert ist, sondern wenn das Makro ausgeführt wird, was auch erklärt, warum die Variable innerhalb des Makros definiert werden muss.
Danke, dass du dir die Zeit genommen hast! Das macht Sinn und ich habe jetzt zusätzliche Werkzeuge, um über Metaprogrammierung nachzudenken: D –