在開始使用巨集(macro)之前,我們要先理解 Elixir 在編譯前會變成的抽象語法樹
AST (Abstract Syntax Tree) 抽象語法樹
quote/2
我們可以使用 quote/2
函式來將目前寫的程式碼轉換為 AST
假裝我們有一個 greet 函式
quote do
greet("Tim", 3)
end
會得到一個 tuple
{:greet, [], ["Tim", 3]}
第一個是函式名稱
第二個是 metadata 是一個 keyword list, 目前範例是空的
第三個是變數
我們也可以試試看現有的函式
quote do
rem(9, 3)
end
結果為
{:rem, [context: Elixir, imports: [{2, Kernel}]], [9, 3]}
跟上面差不多,但多了一些 metadata
Map 也有自己的表達式
quote do
%{name: "Elixir"}
end
{:%{}, [], [name: "Elixir"]}
雖然不是標準的 macro 作法
但是我們可以在這個階段用 Code.eval_quoted/3
直接執行這個被 quote 變成 AST 的程式碼
representation = quote(do: 50 + 50)
{result, binding} = Code.eval_quoted(representation)
result
#=> 100