Do all? and any? guarantee short-circuit evaluation?

Viewed 2302

Testing out some code in both pry and irb, I get the following results:

[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

In [2] and [3] I see that there appears to be short-circuit evaluation that aborts the iteration as soon as possible, but is this guaranteed behaviour? Reading the documentation there is no mention of this behaviour. I realise that I can use inject instead as that will iterate over everything, but I'm interested in finding out what the official Ruby view is.

3 Answers

I think there is some ambiguity here.

Consider the following:

RUBY_VERSION
=> "2.3.7"

When yielding to a block:

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

When not yielding to a block:

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

Seems like condition #2:

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

Is not valid.

Related