2017-10-13 24 views

回答

1

該包使用元編程爲每個HTTP動詞生成函數。動詞的名稱定義here

@http_verbs ~w(head get delete trace options post put patch)a 

該列表遍歷和函數是動態的每個here生成。每個功能的實際主體在generate_api功能here中定義。所以Tesla.get/2實際源this

def unquote(method)(url, body) do 
    request(method: unquote(method), url: url, body: body) 
end 

如果替代method:get,你得到的Tesla.get/2有效的定義:

def get(url, body) do 
    request(method: :get, url: url, body: body) 
end 

你可以閱讀的編譯二郎形式模塊的代碼也是這樣的:

{_, _, bytecode} = :code.get_object_code(Tesla) 
{:ok, {_, [{:abstract_code, {_, ac}}]}} = :beam_lib.chunks(bytecode, [:abstract_code]) 
ac |> :erl_syntax.form_list |> :erl_prettypr.format |> IO.puts 

輸出是巨大的,但如果你仔細看,你會看到生成所有get/2條款:

... 

get(#{'__struct__' := 'Elixir.Tesla.Client'} = [email protected], 
    [email protected]) -> 
    request([email protected], [{method, get}, {url, [email protected]}]); 
get([email protected], [email protected]) when erlang:is_function([email protected]) -> 
    get(#{post => [], pre => [], 'fun' => [email protected], 
     '__struct__' => 'Elixir.Tesla.Client'}, 
    [email protected]); 
get([email protected], [email protected]) when erlang:is_list([email protected]) -> 
    request([{method, get}, {url, [email protected]}] ++ [email protected]). 

... 
相關問題