Bug in Hash#hash? (Ruby 1.8.4)

Hi,

say one = {:a=>:b}
then one.hash != one.clone.hash
is that a bug or correct?

(using ruby 1.8.4 (2005-12-24) [i486-linux])

second question:I want to index use a hash as key in a hashtable, but
it doesnt work (probably because of above problem)

one = {:a=>:b}
two = {:a=>:b}
test[one] = 1
test[two] … nil
test.include? one … true
test.include? two … false
although one == two … true

on the other hand, one.eql?(two) … false (which seems wrong to me, as
matz indicated in 2004, see
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/122510)
and also one.hash != two.hash (as pointed out above, and seems to be
the source of the problem)

so it seems:

  • hash.eql? is wrong (see matz’ earlier message)
  • hash.hash is wrong (try it with dup of itself)

or do i miss something?

Hi,

In message “Re: Bug in Hash#hash? (Ruby 1.8.4)”
on Wed, 20 Sep 2006 23:40:11 +0900, “Eyal O.”
[email protected] writes:

|say one = {:a=>:b}
|then one.hash != one.clone.hash
|is that a bug or correct?
|
|(using ruby 1.8.4 (2005-12-24) [i486-linux])

Currently it’s an intended behavior. Hash is not designed to be hash
key (two hashes are considered to be a same key if they are exactly
the same object). It’s not likely to change in 1.8 series. In 1.9,
maybe.

						matz.

On 9/20/06, Yukihiro M. [email protected] wrote:

Currently it’s an intended behavior. Hash is not designed to be hash
key (two hashes are considered to be a same key if they are exactly
the same object). It’s not likely to change in 1.8 series. In 1.9,
maybe.

And I think more precisely, it’s that hash needs to be implemented so
that a.eql?(b) implies a.hash == b.hash

one = {:a => :b}
two = one.clone

one == two #=> true
one.eql?(two) #=> false

Smalltalkers might recall that Smalltalk has both a Hash which uses
Smalltalks equivalents to Ruby’s hash and ==, and IdentityHash which
uses Smalltalks equivalents to Ruby’s object_id for the hash, and
equal?


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/

On 9/20/06, Yukihiro M. [email protected] wrote:

Recently, 1.9 added Hash#compare_by_identity method which makes Hash
to compare its keys by identity.

And I showed my age, they say that the memory is the second thing to
go, but I forget what the first thing is.

In Smalltalk it’s Dictionary, and IdentityDictionary, but other than
the names Dictionary is a Hash.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Yukihiro M. wrote:

|say one = {:a=>:b}
|then one.hash != one.clone.hash
|is that a bug or correct?
Currently it’s an intended behavior. Hash is not designed to be hash
key (two hashes are considered to be a same key if they are exactly
the same object). It’s not likely to change in 1.8 series. In 1.9,
maybe.
thanks for the clarification.
why was this decided?

is it not useful to have a hash as hash-key? I often use hashes to
emulate named parameter-values, and if I have say a connection pool I
would like to index it based on the connection-parameters (which are
given as a hash of key-value pairs).

does this scenario make sense?

Hi,

In message “Re: Bug in Hash#hash? (Ruby 1.8.4)”
on Thu, 21 Sep 2006 09:34:17 +0900, “Rick DeNatale”
[email protected] writes:

|Smalltalkers might recall that Smalltalk has both a Hash which uses
|Smalltalks equivalents to Ruby’s hash and ==, and IdentityHash which
|uses Smalltalks equivalents to Ruby’s object_id for the hash, and
|equal?

Recently, 1.9 added Hash#compare_by_identity method which makes Hash
to compare its keys by identity.

						matz.

On 9/21/06, Eyal O. [email protected] wrote:

Yukihiro M. wrote:

|say one = {:a=>:b}
|then one.hash != one.clone.hash
|is that a bug or correct?
Currently it’s an intended behavior. Hash is not designed to be hash
key (two hashes are considered to be a same key if they are exactly
the same object).

is it not useful to have a hash as hash-key? I often use hashes to
emulate named parameter-values, and if I have say a connection pool I
would like to index it based on the connection-parameters (which are
given as a hash of key-value pairs).

Not entirely to the point, but…

One issue you have to be aware of if you have a Hash with keys that
are mutable, is that if a key mutates so as to affect the results of
eql?/hash then the hash needs to be rehashed or strange events can
ensue.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/