【问题标题】:Erlang/Elixir guards and arityErlang/Elixir 守卫和 arity
【发布时间】:2015-05-15 04:48:01
【问题描述】:

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

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

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

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

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

这是谈话中的问题:

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

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

【问题讨论】:

  • 只是好奇——这里的用例是什么?守卫条件不应该帮助你避免编写糟糕的代码吗?因此,如果您违反了保护条件,请重新编写代码。
  • 我也只是好奇。我可以想象的一个用例是一个受保护的函数,(例如)只允许 1 到 10 之间的数字。怎么知道呢?答案肯定是“查看文档”或“查看源代码”,但我希望会有诸如“只需使用 SomeModule.show_guards/1 函数并传递感兴趣的函数”之类的答案。

标签: erlang elixir arity pattern-guards


【解决方案1】:

目前无法在不查看来源的情况下内省此信息。

【讨论】:

  • 可以查看生成的BEAM代码。 :-) 开个玩笑。
  • 现在有一种方法可以在不查看源代码的情况下查看函数的守卫和数量。 Elixir 1.5 引入了Exception.blame/3,它在某些错误时被调用(例如FunctionClauseError)。 Exception.blame/3 精确地显示了这个问题(以及更多)中的信息。需要 Erlang/OTP 20。在这里查看:elixir-lang.org/blog/2017/07/25/elixir-v1-5-0-released
【解决方案2】:

如果梁文件中有调试信息,则可以创建一个库来解析它并为您提供所需的内容,而无需查看源代码。这是 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 的示例模块,它有两个函数也叫 fact,你可以得到上面的输出。

抽象代码中的子句将具有带有 atom op 的守卫。这些也可以检索。

【讨论】:

    猜你喜欢
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2023-03-27
    • 2014-03-31
    • 1970-01-01
    相关资源
    最近更新 更多