[BUG] Dictionary equality test

Richard A. O'Keefe ok at cs.otago.ac.nz
Fri Jun 7 04:16:04 UTC 2002


Some code I was writing today got derailed because Dictionary>> =
doesn't work the way I expected.

In Squeak 3.0.1, Dictionary doesn't have an #= of its own.
It inherits the one from Set, so we have
Dictionary(Set)>>
= aSet
    (aSet isKindOf: Set) ifFalse: [^false].
    self size = aSet size ifFalse: [^false].
    self do: [:each | (aSet includes: each) ifFalse: [^false]].
    ^true

This really makes no sense for Dictionaries.
Example:

    d1 := Dictionary new at: #a put: false; yourself.
    d2 := Dictionary new at: #b put: false; yourself.
    d1 = d2
==> true

These are clearly different dictionaries.  Yet they compare equal.

The code as written *would* work for Dictionary objects if
*(1) aDictionary do:  iterated over associations and
*(2) aDictionary includes:  checked for association membership
but both of those are false:
+(1) aDictionary do:  iterates over the *values* and
+(2) aDictionary includes:  checks for *value* membership.

The effect is that when you compare two dictionaries,
 - they must have the same number of keys and
 - each value in the first must be a value in the second

Note that this isn't even Set equality.
    d1 := Dictionary new at: #a put: false; at: #b put: false; yourself.
    d2 := Dictionary new at: #x put: false; at: #y put: true;  yourself.
    d1 = d2
==> true

These two dictionaries don't even satisfy (d1 values asSet = d2 values asSet),
but they compare equal.

This effect is so bizarre that I don't believe anyone could be relying on it.

Has it been fixed?

If not, would this be an acceptable addition?

Dictionary>>
= aDictionary
    (aDictionary isKindOf: Dictionary) ifFalse: [^false].
    self size = aDictionary size ifFalse: [^false].
    self associationsDo: [:assoc|
        (aDictionary at: assoc key ifAbsent: [^false]) = assoc value
            ifFalse: [^false]].
    ^true




More information about the Squeak-dev mailing list