#286 new
Martin Häcker

-hash is broken on CPArray

Reported by Martin Häcker | April 30th, 2009 @ 02:06 AM

It breaks the contract that two arrays which are -isEqual: also need to report the same -hash value.

Patch and tests included

It's also the same way that GnuStep and Cocotron implement this - I was quite surprised how simple they implemented it.


Comments and changes to this ticket

  • Ross Boucher

    Ross Boucher April 30th, 2009 @ 08:33 AM

    Why do both array's need to return the same hash value? That doesn't seem to be documented anywhere in the Cocoa docs.

    This code seems incredibly dangerous to me. You're essentially saying that all kinds of arrays that have nothing to do with each other could be considered equal. This will break anything that uses hash as a unique identifier (for example, KVO/Bindings, and I'm sure other code in Cappuccino).

  • Ross Boucher

    Ross Boucher April 30th, 2009 @ 09:05 AM

    I spoke before I understood what I was talking about.

    From the documentation for hash:

    @"If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection."

    Our implementation of hash does not behave this way. Perhaps we should consider changing our hash to become address, and re-implementing hash the Cocoa way?

  • Martin Häcker

    Martin Häcker April 30th, 2009 @ 10:23 AM

    I'm not sure I understand you correctly, -[CPObject hash] does return __adress, I haven't checked all the other objects, but all objects who redefine -isEqual: need their own implementation that matches the contract.

    The one which I provided for CPArray - and I checked it against the two other Cocoa implementations I know, which do it the same way. (Also it makes sense: The Implementation needs to be FAST, and it needs to be the same when two objects are -isEqual:

    I also checked against some examples on Cocoa and it behaves the same way.

  • Ross Boucher

    Ross Boucher April 30th, 2009 @ 10:27 AM

    My point was that -hash works differently in Cappuccino than in Cocoa (something I previously had not realized).

    We need access to __address as a method, which is what hash has been doing for us. To make -hash actually correct, we'll need to add -address and update all of the cappuccino code that relies on hashes being globally unique.

  • Martin Häcker

    Martin Häcker April 30th, 2009 @ 10:30 AM

    Too late to finish sentences...

    The one which I provided does fit the contract and also behaves the same way that the others do.

  • Ross Boucher

    Ross Boucher April 30th, 2009 @ 10:32 AM

    Yes, but it breaks parts of Cappuccino that expect the current behavior. For example, KeyValueObserving and CPWindow both rely on the value of -hash as a unique index into various data structures.

  • Martin Häcker

    Martin Häcker April 30th, 2009 @ 10:54 AM

    Oh damn.

    I just had a look around in the source and lots of objects like CPDictionary, CPData, CPDate and CPNull don't overide -hash but should. (And most should probably also overide isEqual:)

    Uh oh....

    Yes, this is going to take some work.

  • Martin Häcker

    Martin Häcker April 30th, 2009 @ 11:11 PM

    Can't resist...

    As a good person once said: In God we trust - for everything else we have UnitTests.


Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

The Cappuccino Web Framework, including AppKit, Foundation, and Objective-J.

Shared Ticket Bins