Never use #newFrom: with associations from another dictonary if you reuse the first after.
 
The bug is actually deeper than you know:
dic1 := Dictionary newFrom:{'test' -> 4}.
dic2 := IdentityDictionary newFrom: {'test' copy -> 4}.
dic1 = dic2.
dic2 = dic1.
 
Depending on the order, they are equal or inequal.
 
The bug is caused by Dictionary>>= using a polymorphic type test #isDictionary. Squeak is unaffected: its #= uses a hardcoded class == test. The least disruptive fix I can think of is adding another type test #isIdentityDictionary in Dictionary that returns false but returns true for every identity dictionary class (like SmalllIdentityDictionary). Then only compare the associations if "self isIdentityDictionary = aDictionary isIdentityDictionary".
 
I will open an issue.
 
Sent: Friday, October 09, 2015 at 10:51 AM
From: "Henrik Johansen" <[email protected]>
To: "Pharo Development List" <[email protected]>
Subject: Re: [Pharo-dev] hash and Collections
 
On 09 Oct 2015, at 4:33 , Esteban Lorenzano <[email protected]> wrote:
 
 
On 09 Oct 2015, at 16:21, Gabriel Cotelli <[email protected]> wrote:
 
If the collection implements = using the objects it holds then you need to consider at least some of them in the hash calculation. I can't conceive a hash calculation for this case independent of the contents (well,  just hardcode a number but this will lead to always collide if used as a key in a hashed collection).
 
it is not :)
 
 
I'm with Levente here, I think the hash implementation is reasonable. And I wouldn't use a mutable object as key in a hashed collection.
 
no idea… I’m not using it, just arrive to that method random and I cannot understand it. 
I still believe is wrong. 
It's not.
 
Either Dictionary >> #= or IdentityDictionary >> #species in Pharo *is* broken though.
 
dic1 := Dictionary newFrom:{1 -> 4}.
dic2 := IdentityDictionary newFrom: dic1 associations .
 
dic1 = dic2     true
dic1 hash = dic2 hash false
 
Cheers,
Henry

Reply via email to