2013-12-19 39 views
3

测试了两种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视图是什么。

+0

“garanteed”是什么意思?在[2]中,当它发现任何一个时,它停止评估,即> 1。我没有看到任何理由为什么它应该更进一步。对于[3]也是如此,当它发现任何错误时,它就停止。有很多其他的方法来评估对象的整个句子... –

+0

我的意思是说,因为数组中有一个零,如果我使用'注入'我得到一个'ZeroDivisionError',但会符合Ruby实现(假设有一个规范要符合!)总是在尽可能早的时候停下来,而不要试图用零来除? –

+3

我相信它甚至没有定义'any?'或'all?'从头到尾遍历数组。为了保存在Ruby版本中,你不能做出这样的假设。对于一个单一的ruby版本来说可能是好的。 – tessi

回答

6

是。

在红宝石标准的最终draftall?被定义为这样:

  1. 调用方法each在接收机
  2. 对于每个元素X其中,该方法each yeilds:
    1. 如果给出块,用X作为参数调用块。如果此呼叫返回虚假物品,返回虚假
    2. 如果没有给出块,并且X是虚假物体,返回虚假
  3. 返回true

请注意在步骤2中的单词返回。这保证了短路评估。 any?的定义相似。然而,标准仍然是一个草案,我不知道哪些Ruby实现(如果有的话)的目标是符合标准。

3

any? method只是通过Enumerable实现''的逻辑功能。它可以被解释为声明:

Y = X1 V; X2 V X3配... v XN

而且all? method实现了对在Enumerable '' 的逻辑功能。它也可以被解释为声明:

Y = X1 * X2 * X3 * ... * XN

由于ArrayEnumerable,它包含的方法也。因此,对于方法any?true(正好既不是nil也不是false)的结果与true结果中断枚举结果。在例子中,产生成为上的数字真正,所以方法打破了执行的回报true

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

你也可以申请DeMorgan's rule的功能any?,并使用all?方法:

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

对于方法all?false或的首次出现结果做类似的事情,即返回false。在例子中,产生成为上数 ,所以方法打破了执行的回报false

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

而且随着DeMorgan's transformation使用any?方法:

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