Ruby gotcha? [].all? always returns true

Something in caught me out today. I wanted to test that the contents
of the array where all instances of particular class, and if not, do
stuff. The example isn't exactly what my code did, but it illustrates
my point:

if not my_arr.all? { |i| i.is_a(Integer) }
  # Do stuff
end

I expecting it to 'do stuff', however I found it was not. I discovered
that 'my_arr' was empty, which was not a surprise, but what did
surprise me was that all? called on an empty array appears to always
return true.

I don't know about you, but these seems counter-intuitive to me. Does
anyone agree or disagree?

I've now resorted to any? instead, like as follows:

if not my_arr.any? { |i| not i.is_a(Integer) }
  # Do stuff
end

As far as it seems [].any? always returns false. The code should also
be slightly more efficient as it doesn't always have to check every
item of the array, not that I expect it to get very big.

Something in caught me out today. I wanted to test that the contents
of the array where all instances of particular class, and if not, do
stuff. The example isn't exactly what my code did, but it illustrates
my point:

if not my_arr.all? { |i| i.is_a(Integer) }
  # Do stuff
end

I expecting it to 'do stuff', however I found it was not. I discovered
that 'my_arr' was empty, which was not a surprise, but what did
surprise me was that all? called on an empty array appears to always
return true.

I don't know about you, but these seems counter-intuitive to me. Does
anyone agree or disagree?

I've now resorted to any? instead, like as follows:

if not my_arr.any? { |i| not i.is_a(Integer) }
  # Do stuff
end

As far as it seems .any? always returns false. The code should also
be slightly more efficient as it doesn't always have to check every
item of the array, not that I expect it to get very big.

Vacuous truth - Wikipedia

···

On 4/26/07, Dan Stevens (IAmAI) <dan.stevens.iamai@gmail.com> wrote:

Yeah, it is suprising at first sight but that's standard semantics in math.

A for all statement like that holds always for the empty set because otherwise you'd need to show an element of the empty set (impossible) for which the test is false. The reason is

   not for all x in S P(x)

is logically equivalent to

   there exists x in S such that not P(x)

This is a corner case, note that it does not depend on P.

-- fxn

···

On Apr 27, 2007, at 12:55 AM, Dan Stevens (IAmAI) wrote:

Something in caught me out today. I wanted to test that the contents
of the array where all instances of particular class, and if not, do
stuff. The example isn't exactly what my code did, but it illustrates
my point:

if not my_arr.all? { |i| i.is_a(Integer) }
# Do stuff
end

I expecting it to 'do stuff', however I found it was not. I discovered
that 'my_arr' was empty, which was not a surprise, but what did
surprise me was that all? called on an empty array appears to always
return true.

I don't know about you, but these seems counter-intuitive to me. Does
anyone agree or disagree?

"Dan Stevens (IAmAI)" <dan.stevens.iamai@gmail.com> writes:

if not my_arr.all? { |i| i.is_a(Integer) }
# Do stuff
end

I expecting it to 'do stuff', however I found it was not. I discovered
that 'my_arr' was empty, which was not a surprise, but what did
surprise me was that all? called on an empty array appears to always
return true.

I don't know about you, but these seems counter-intuitive to me. Does
anyone agree or disagree?

It seems perfectly intuitive to me.

There's a local law that states that all dogs must wear leashes when
not confined behind a fence. We are in full compliance with that law,
even though our front yard has no fence and we own no leashes - this
is because we have no dogs.

I've now resorted to any? instead, like as follows:

if not my_arr.any? { |i| not i.is_a(Integer) }
# Do stuff
end

As far as it seems .any? always returns false. The code should also
be slightly more efficient as it doesn't always have to check every
item of the array, not that I expect it to get very big.

Actually, all? has the same efficiency characteristics. That is, the
instant it finds something false, it returns false.

···

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.to_a[1] )
       puts "s=%q(#{s})",s.to_a[1]

A good explanation.

Let me elaborate it a bit more. The parallelism there goes: "you are within the law if all your dogs satisfy <something>". Can I say that "all my dogs satisfy <something>" is true if I have no dog? Why? In what sense can I say something holds in an empty collection?

To see why the response is yes, I think we need to go a little step further: The point is that a policeman should prove one of your dogs does not satisfy <something> to say you've break the law. It's because that's impossible that you are within the law as far as that law concerns. Therefore, since you are either within or outside the law, "all your dogs satisfy <something>" necessarily holds.

That's the formal equivalence I mentioned earlier (what makes logicians define for all and there exists that way is our intuitive reasoning about dogs and laws, formal logic as such does not justify per se that's OK that way.)

-- fxn

···

On Apr 27, 2007, at 2:21 PM, Daniel Martin wrote:

"Dan Stevens (IAmAI)" <dan.stevens.iamai@gmail.com> writes:

if not my_arr.all? { |i| i.is_a(Integer) }
# Do stuff
end

I expecting it to 'do stuff', however I found it was not. I discovered
that 'my_arr' was empty, which was not a surprise, but what did
surprise me was that all? called on an empty array appears to always
return true.

I don't know about you, but these seems counter-intuitive to me. Does
anyone agree or disagree?

It seems perfectly intuitive to me.

There's a local law that states that all dogs must wear leashes when
not confined behind a fence. We are in full compliance with that law,
even though our front yard has no fence and we own no leashes - this
is because we have no dogs.