Recipe 5.5. Using an Array or Other Modifiable Object as a Hash Key
Suppose you want a reliably hashable Array class. If you want this behavior universally, you can reopen the Array class and redefine hash to give you the new behavior. But it's safer to define a subclass of Array that implements a reliable-hashing mixin, and to use that subclass only for the Arrays you want to use as hash keys:
module ReliablyHashable
def hash
return object_id
end
end
class ReliablyHashableArray < Array
include ReliablyHashable
end
It's now possible to keep track of the jewels:
coordinates = ReliablyHashableArray.new([10,5])
treasure_map = { coordinates => 'jewels' }
treasure_map[coordinates] # => "jewels"
# Add a z-coordinate to indicate how deep the treasure is buried.
coordinates.push(-5)
treasure_map[coordinates] # => "jewels"
Ruby performs hash lookups using not the key object itself but the object's hash code (an integer obtained from the key by calling its hash method). The default implementation of hash, in Object, uses an object's internal ID as its hash code. Array, Hash, and String override this method to provide different behavior.