做所有? 还有什么? 保证短路评估?

pryirb测试一些代码,我得到以下结果:

 [1] pry(main)> a = [1, 3, 5, 7, 0] => [1, 3, 5, 7, 0] [2] pry(main)> a.any? {|obj| p obj; 3 / obj > 1} 1 => true [3] pry(main)> a.all? {|obj| p obj; 3 / obj > 1} 1 3 => false 

[2][3]我看到似乎存在短路评估,尽快中止迭代,但是这种保证行为是什么? 阅读文档没有提到这种行为。 我意识到我可以使用inject ,因为它将迭代所有内容,但我有兴趣找出官方的Ruby视图是什么。

是。

在Ruby标准的最终草案中, all? 定义如下:

  1. 在接收器上调用each方法
  2. 对于每个方法的each元素X:
    1. 如果给出了块,则以X为参数调用块。 如果此调用返回falseish对象,则返回 false
    2. 如果未给出块,并且X是假的对象,则返回 false
  3. 回归真实

注意步骤2中的返回字。这可以保证短路评估。 any? 是类似的定义。 然而,该标准仍然是草案,我不知道哪些Ruby实现(如果有的话)旨在符合标准。

any? 方法只是在Enumerable实现’ ‘逻辑function。 它可以解释为声明:

y = x1 v x2 v x3 v … v xn

而这all? 方法在Enumerable实现’ ‘逻辑function。 它也可以解释为声明:

y = x1 * x2 * x3 * … * xn

由于ArrayEnumerable ,它还包括那些方法。 那么,对于any?方法any? 第一次出现的true (确切地说既不是nil也不是false )结果打破了枚举的true结果。 例如,在数字4上yielding变为true ,因此方法会中断执行返回true

 [1,2,3,4,5].any? {| x | puts x ; x > 3 } # 1 # 2 # 3 # 4 # => true 

您还可以将DeMorgan的规则应用于该函数any? ,并使用all? 方法:

 ![1,2,3,4,5].all? {| x | puts x ; x <= 3 } # 1 # 2 # 3 # 4 # => true 

对于方法all? falsenil结果的第一个偶然事件做类似的事情,即返回false 。 在示例中,数字3上的yielding变为false ,因此方法会中断执行返回false

 [1,2,3,4,5].all? {| x | puts x ; x < 3 } # 1 # 2 # 3 # => false 

而DeMorgan的改造使用了any? 方法:

 ![1,2,3,4,5].any? {| x | puts x ; x >= 3 } # 1 # 2 # 3 # => false