2017-10-13 3 views

Répondre

1

Ce paquet génère les fonctions pour chaque verbe HTTP en utilisant la méta-programmation. Les noms des verbes sont définis here

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

Cette liste est itéré et les fonctions sont générées dynamiquement pour chaque here. Le corps réel de chaque fonction est défini dans generate_api fonction here. Donc, la source réelle de Tesla.get/2 est this:

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

Si vous substituez method avec :get, vous obtenez la définition efficace de Tesla.get/2:

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

Vous pouvez lire le formulaire Erlang compilé de la le code du module ainsi que ceci:

{_, _, 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 

La sortie est énorme mais si vous regardez attentivement, vous verrez toutes les clauses get/2 qui sont générés:

... 

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]). 

...