On Wed, 7 Nov 2001 puzzled186 / hotmail.com wrote: > I'd like to be able to do something like: > {1..100=>"a",101..300=>"c", 500..1000=>"r"} > > The syntax accepts it, but it doesn't behave the way I'd like (always > comes up nil). As matju pointed out last night on #ruby-lang, Range does not override Kernel#hash and Kernel#eql?. The default behavior for an object that does not override these functions is for the hash value to be the object id and for eql? to test for object equality (same object), not value equality (same value). The following demonstrates the problem: h = {1..100=>"a",101..300=>"c", 500..1000=>"r"} p h[1..100] #=> nil class Range def hash # Is this a good hash function? self.begin + (11 * self.end) + (17 * (self.exclude_end? ? 23 : 29)) end end h = {1..100=>"a",101..300=>"c", 500..1000=>"r"} p h[1..100] #=> nil class Range def eql?(other) self == other end end h = {1..100=>"a",101..300=>"c", 500..1000=>"r"} p h[1..100] #=> "a" Is this fixed in 1.7? I suppose the moral of the story is that if you write a class that you expect to be able to put into a Hash, then you should override hash() and eql?. It's not enough to override hash() and ==, though: class Foo def initialize(x) @x = x end def hash() @x end def ==(other) @x == other.x end attr_reader :x end h = Hash[Foo.new(1) => 1, Foo.new(2) => 2, Foo.new(3) => 3] p h[Foo.new(1)] #=> nil class Foo def eql?(other) self == other end end h = Hash[Foo.new(1) => 1, Foo.new(2) => 2, Foo.new(3) => 3] p h[Foo.new(1)] #=> 1 Paul