Daniel Martin
9/1/2006 2:06:00 PM
"Jia Pu" <very.funny.j@gmail.com> writes:
> Thanks, that works.
> I am wondering the requirement of #eql? is necessary. If the programmer
> wants to have non-equal objects to have same hash value, it is totally up to
> the programmer.
I assume you are asking why defining .eql? is necessary. (You seem to
have dropped the word "why" in your question)
If two objects have the same hash value, this does not mean that they
should overwrite each other when used as keys! In fact, that would be
disasterous as hash collisions are a fact of life - has must be a
Fixnum, and there are only so many Fixnums to go around.
For example:
irb(main):001:0> h = Hash.new
=> {}
irb(main):002:0> h[1] = 'Value for 1'
=> "Value for 1"
irb(main):003:0> h[4294967298] = 'Value for a really big number'
=> "Value for a really big number"
irb(main):004:0> h[1]
=> "Value for 1"
irb(main):005:0> 1.hash
=> 3
irb(main):006:0> 4294967298.hash
=> 3
Fortunately, 1.eql?(4294967298) is false, so I can store different
values in my hash.
Note that the definition of .eql? and == do not need to have anything
to do with each other, or with the definition of ===. However, it is
generally very good practice to make sure that the following
implication chain holds:
(a.eql?(b)) implies (a == b) implies (a === b)
Also, eql? and == should be symmetric (that is, it should make no
difference switching a and b for those two methods).
--
s=%q( Daniel Martin -- martin@snowplow.org
puts "s=%q(#{s})",s.map{|i|i}[1] )
puts "s=%q(#{s})",s.map{|i|i}[1]