[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [Discuss] ruby, enum all? bug

Eric I.

6/12/2008 5:54:00 PM

Zach Dennis wrote:
> Does anyone else think this is weird behavior in ruby 1.8.x ?
> [].all?{ false } # => true
>
> The implementation of enum.all? defaults the result to true, and then relies
> on iterating over the elements to set it to false. It seems like it should

Daniel Parker wrote:
> I agree, even though the docs do explain exactly what it does, it seems like
> it shouldn't return true. Maybe returning nil would be more appropriate when
> there are no elements.

Craig Demyanovich wrote:
> That the code does what the docs indicate is beside the point (though
> it's good that they're in agreement ;-) ). The behavior is definitely
> not what I would've expected, which is to return false. My vote is to
> just return false when there are no elements. I like to avoid nil
> whenever possible (which is almost always) because it forces client
> code to use a conditional to check for it.

I guess I'm a contrarian here, because I think Ruby's current behavior
is correct, and I think I can make a decent case for it. These kinds
of "edge" conditions can often be counter-intuitive, although if you
look at the larger picture they make perfect sense. Weren't you a
little put off when you first learned that n**0 == 1 (if n != 0)? Or
when you learned that 0! == 1? But if powers and factorials didn't
behave that way, a lot of simple stuff would break (like the formulas
for permutations and combinations).

First, the content of the block is irrelevant as it should never be
executed when the collection is empty. The block Zach uses though is
very well chosen, in that it really strikes his point home.

Second, all? (along with any?) are defined by the Enumerable module,
which is designed to with collections of various sorts, not just
arrays. All a collection has to do is implement the each method, and
Enumerable handles everything else. So the behavior of all? (and
any?) should make sense in this very general context -- including
sets, trees, linked lists, etc.

Third, if *all* members of a collection have a property, then *any
subset* of that collection should have that property. So if I have a
collection of accounts that are all overdue, any subset of those
accounts should be overdue as well, right? And the empty collection
is a valid subset.

[account1, account2, account3].all? { |a| a.overdue? }
=> true
[account1].all? { |a| a.overdue? }
=> true
[].all? { |a| a.overdue? }
=> true

If all? on an empty collection simply returns false, then we lose this
valuable property.

Fourth, there is a symmetry between all? and any?. In fact, it's the
same symmetry we have between && and || using De Morgan's Law:

P && Q == !(!P || !Q)
P || Q == !{!P && !Q)

With all? and any? we have these equivalents:

collection.all? { |member| member.property? } == ! collection.any? {
|member| ! member.property? } # note two inversions
collection.any? { |member| member.property? } == ! collection.all? {
|member| ! member.property? }

Let's take accounts and being overdue as our specific example. If in
a given collection all accounts are overdue, then it *can't* be the
case that *any *of the accounts are *not* overdue:

[account1, account2, account3].all? { |a| a.overdue? } == ! [account1,
account2, account3].any? { |a| ! a.overdue? } # note the two
inversions

Those expressions must be equivalent. And so should this:

[].all? { |a| a.overdue? } == ! [].any? { |a| ! a.overdue? } # note
the two inversions

Changing the behavior of all? would break this identity.

And note that just as:

[].all? { blah }

will always return true:

[].any? { blah }

will always return false.

So even though it seems counter-intuitive at first blush, in the
larger context it makes perfect sense, and it would be a mistake to
change it.

Eric

====

LearnRuby.com offers Rails & Ruby HANDS-ON public & ON-SITE workshops.
Ruby Fundamentals Workshop June 16-18 Ann Arbor, Mich.
Ready for Rails Ruby Workshop June 23-24 Ann Arbor, Mich.
Ruby on Rails Workshop June 25-27 Ann Arbor, Mich.
Ruby Plus Rails Combo Workshop June 23-27 Ann Arbor, Mich.
Please visit http://Lea... for all the details.

1 Answer

Robert Dober

6/12/2008 6:12:00 PM

0

On Thu, Jun 12, 2008 at 7:54 PM, Eric I. <rubytraining@gmail.com> wrote:
I am surprised that some of you find it counterproductive that [].all?
always returns true.
IIRC that is one of the basic axioms or theorems of predicate logic,
any statement is true if applied to all members of the empty set.
But maybe I am wrong, anyway I am quite happy that Ruby does it the
way I learnt it in school ;)

Cheers
Robert




--
http://ruby-smalltalk.blo...

---
As simple as possible, but not simpler.
Albert Einstein