Erlang/Elixir 守卫和阿瑞斯

Erlang/Elixir guards and arity

有没有办法在不查看源代码的情况下查看函数的守卫?

给定一个示例函数(在 Elixir 中):

def divide(x, y) when y != 0 do
  x / y
end

如何在无法访问源代码的情况下确定 divide/2 上有一名警卫,以及如何找到有关该警卫的信息或该警卫对模式匹配的期望?

我正在观看 Chris McCord(Elixir 的 Phoenix Framework 的创建者)在 Ruby Conf 2014 上的演讲。在演讲中,Chris 正在描述守卫,有人问是否有一种方法可以检查一个函数显示函数的守卫。

这是演讲中的问题:

https://www.youtube.com/watch?v=5kYmOyJjGDM&t=5188

问题是在视频的 t= 时间后不久提出的。

目前,不查看源代码就无法反省此信息。

如果 beam 文件中有调试信息,则可以创建一个库来解析它并在不查看源代码的情况下为您提供所需的信息。这是 Erlang 中的一个示例,说明如何获取函数的元数。

1> GetArities = 
  fun(Module, FunName) ->
    {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Module,[abstract_code]),
    lists:foldl(
      fun({function, _Line, Fun, Arity, _Clauses}, FunArities) when Fun == FunName ->
            [Arity | FunArities];
          (_, FunArities) ->
            FunArities
      end, [], AC)
  end.

2> GetArities(fact,fact).
[1,0]

对于一个名为 fact 的示例模块,其中包含 2 个也名为 fact 的函数,您可以获得上述输出。

抽象代码中的子句将具有带有原子操作的守卫。那些也可以检索。