9

Why does

[].all?{|a| a.include?('_')} 

return true?

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
psjscs
  • 531
  • 3
  • 9
  • 1
    Isomorphic to [Why does IQueryable.All() return true on an empty collection?](http://stackoverflow.com/questions/2195289/why-does-iqueryable-all-return-true-on-an-empty-collection) – Josh Lee Nov 04 '10 at 05:35

4 Answers4

10

Your code asks about the truth of the following statement: "For all elements a in the empty list, a includes the character '_'." Because there are no elements in the empty list, the statement is true. (This is referred to as vacuous truth in logic.) It might be easier to understand if you instead try to find a way to make that expression false. This would require having at least one element in the empty list which did not contain '_'. However, the empty list is empty, so no such element can exist. Therefore, the statement can't meaningfully be false, so it must be true.

bcat
  • 8,833
  • 3
  • 35
  • 41
7

all? will pass every element of the array to the block {|a| a.include?('_')}, and return true if the block doesn't return false or nil for any of the elements. Since the array has no elements, the block will never return false or nil and so all? returns true.

Nabb
  • 3,434
  • 3
  • 22
  • 32
2

all? returns true if the block never returns false or nil. The block never gets called, therefore it never returns false or nil and therefore all? returns true.

Reese Moore
  • 11,524
  • 3
  • 24
  • 32
1

Even

[].all?{ false }

returns true, for the reasons explained in bcat's answer.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338