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

Ken*_*Y-N 8 ruby

在这两个测试一些代码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
Run Code Online (Sandbox Code Playgroud)

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

Max*_*Max 9

是.

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

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

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


Мал*_*евъ 5

any?方法只是实现了“”逻辑功能Enumerable。它可以被解释为声明:

y = x1 v x2 v x3 v ... v xn

all?方法实现了“”的逻辑功能Enumerable。它也可以被解释为声明:

y = x1 * x2 * x3 * ... * xn

由于ArrayEnumerable,因此它也包含这些方法。因此,对于该方法,any?第一次出现true(既不是nil也不是false)结果会破坏true结果的枚举。在示例中,yield在数字4上变为true,因此这些方法会中断返回的执行:true

[1,2,3,4,5].any? {| x | puts x ; x > 3 }
# 1
# 2
# 3
# 4
# => true
Run Code Online (Sandbox Code Playgroud)

您还可以将DeMorgan 规则应用于function any?,并使用all?method :

![1,2,3,4,5].all? {| x | puts x ; x <= 3 }
# 1
# 2
# 3
# 4
# => true
Run Code Online (Sandbox Code Playgroud)

对于该方法,all?第一次出现的falsenil结果会执行类似的操作,即返回false。在示例中,yield在数字3上变为false,因此这些方法会中断返回的执行:false

[1,2,3,4,5].all? {| x | puts x ; x < 3 }
# 1
# 2
# 3
# => false
Run Code Online (Sandbox Code Playgroud)

并用DeMorgan 的变换来使用any?方法:

![1,2,3,4,5].any? {| x | puts x ; x >= 3 }
# 1
# 2
# 3
# => false
Run Code Online (Sandbox Code Playgroud)