From: Robert Klemme Date: 2009-03-19T03:02:24+09:00 Subject: Re: Is it safe to override #hash and #eql? to enable hash key equality? On 18.03.2009 18:59, James wrote: > Hi, > > I would like to use object instances as hash keys where two objects > containing the same datum both have the same key value. This does not > work by default (as expected given that these are two different > instances): > > class Foo > def initialize(datum) > @datum = datum > end > end > > # Two hash keys for the same datum > a = {Foo.new(:baz) => 1, Foo.new(:baz) => 2} > p a > > # => {#=>1, # @datum=:baz>=>2} > > However, this functionality can be obtained by overriding Object#hash > and Object#eql?: > > class Bar > > attr_reader :datum > > def initialize(datum) > @datum = datum > end > > def hash > @datum.hash > end > > def eql?(other) > @datum.eql? other.datum > end > > end > > # One hash key for the same datum > b = {Bar.new(:baz) => 1, Bar.new(:baz) => 2} > p b > > #=> {#=>2} > > My simple question is if this is safe/normal/OK for my intentions. Not only that: this is exactly how one should do it. > Based on perusal of the online Ruby documentation it looks like #eql? > has been overridden in a number of sub-classes for the same purpose. > But I wanted to get feedback from the community - has anyone here > tried this? Are there any known side-effects? No, your use is absolutely correct. This is what this methods are meant for. The only thing to remark is this: you can save yourself a lot typing by doing: Bar = Struct.new :datum If you need additional methods in that class you can even do Bar = Struct.new :datum do def another_method 123 end end Kind regards robert