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

时间:2013-12-19 06:15:12

标签: 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

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

3 个答案:

答案 0 :(得分:9)

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

  1. 在接收方
  2. 上调用方法each
  3. 对于方法each生成的每个元素X:
    1. 如果给出了块,则以X为参数调用块。如果此调用返回虚假对象,则返回 false
    2. 如果没有给出阻止,而X是虚假对象,则返回 false
  4. 返回 true
  5. 请注意步骤2中的 return 一词。这可以保证短路评估。 any?的定义类似。但是标准仍然是草案,我不知道哪些Ruby实现(如果有的话)是符合标准的。

答案 1 :(得分:3)

any? method只是在Enumerable上实现了''逻辑功能。它可以解释为声明:

  

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

all? methodEnumerable上实现了''逻辑功能。它也可以解释为声明:

  

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

由于ArrayEnumerable,因此它还包括这些方法。因此,对于方法any?true(完全没有nilfalse)结果的第一次出现会导致true结果的枚举失效。例如, yielding 在数字 4 上变为 true ,因此这些方法会使执行返回true

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

此外,您可以将DeMorgan's rule应用于[{1}}功能,并使用any?方法:

all?

对于方法![1,2,3,4,5].all? {| x | puts x ; x <= 3 } # 1 # 2 # 3 # 4 # => true all?false结果的第一次出现会做类似的事情,即返回nil。例如, yielding 在数字 3 上变为 false ,因此这些方法会中断执行返回false

false

DeMorgan's transformation使用[1,2,3,4,5].all? {| x | puts x ; x < 3 } # 1 # 2 # 3 # => false 方法:

any?

答案 2 :(得分:1)

我认为这里有一些歧义。

考虑以下事项:

RUBY_VERSION
=> "2.3.7"

当屈服于一个块时:

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

当不屈服于块时:

def a
  puts "in a"
  true
end

def b
  puts "in b" 
  false
end

def c
  puts "in c"
  true
end

[a,b,c].all?
# in a
# in b
# in c
# => false

看起来像条件​​ #2:

<块引用>

If block is not given, and X is a falseish object, return false.

无效。