Poul
Poul

Reputation: 3476

How to make object instance a hash key in Ruby?

I have a class Foo with a few member variables. When all values in two instances of the class are equal I want the objects to be 'equal'. I'd then like these objects to be keys in my hash. When I currently try this, the hash treats each instance as unequal.

h = {}
f1 = Foo.new(a,b)
f2 = Foo.new(a,b)

f1 and f2 should be equal at this point.

h[f1] = 7
h[f2] = 8
puts h[f1]

should print 8

Upvotes: 35

Views: 18380

Answers (2)

Mark
Mark

Reputation: 5609

See Hash:

Hash uses key.eql? to test keys for equality. If you need to use instances of your own classes as keys in a Hash, it is recommended that you define both the eql? and hash methods. The hash method must have the property that a.eql?(b) implies a.hash == b.hash.

The eql? method is easy to implement: return true if all member variables are the same. For the hash method, use [@data1, @data2].hash as Marc-Andre suggests in the comments.

Upvotes: 64

Sniggerfardimungus
Sniggerfardimungus

Reputation: 11831

Add a method called 'hash' to your class:

class Foo
  def hash
    return whatever_munge_of_instance_variables_you_like
  end
end

This will work the way you requested and won't generate different hash keys for different, but identical, objects.

Upvotes: -3

Related Questions