如何在Elixir Tesla中定义方法函数调用以及源代码在哪里?

时间:2017-10-13 10:37:37

标签: elixir

我正在查看HTTP客户端软件包Tesla的源代码并尝试查找Tesla.get / 2函数的源代码,但我无法在此处找到它,就像函数一样对于其他http方法。 BTW也不能查看来源'来自在线文档的链接。我很困惑,有人可以解释一下吗?

1 个答案:

答案 0 :(得分: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

您可以阅读模块代码的已编译Erlang格式,如下所示:

{_, _, 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'} = _@1,
    _@2) ->
    request(_@1, [{method, get}, {url, _@2}]);
get(_@1, _@2) when erlang:is_function(_@1) ->
    get(#{post => [], pre => [], 'fun' => _@1,
      '__struct__' => 'Elixir.Tesla.Client'},
    _@2);
get(_@1, _@2) when erlang:is_list(_@2) ->
    request([{method, get}, {url, _@1}] ++ _@2).

...