Just had a quick look at the Ruby source and it looks like it doesn't compare the hash but uses the key object's == method to identify the right key. So to test the theory I did some experiments:
2.0.0-p247 :010 > test = {}
=> {}
2.0.0-p247 :011 > a = [1,2]
=> [1, 2]
2.0.0-p247 :012 > test[a]
=> nil
2.0.0-p247 :013 > test[a] = 'cool'
=> "cool"
2.0.0-p247 :014 > test[a]
=> "cool"
2.0.0-p247 :015 > a = [1,2,3]
=> [1, 2, 3]
2.0.0-p247 :016 > test[a]
=> nil
2.0.0-p247 :017 > a = [1,2]
=> [1, 2]
2.0.0-p247 :018 > test[a]
=> "cool"
The reason why we get the nil is because [1,2] ==[1,2,3] is false. Another experiment with ActiveRecord using 2 models and 2 records with the same id:
2.0.0-p247 :019 > test = {}
=> {}
2.0.0-p247 :020 > test[Role.first] = "foo"
Role Load (0.3ms) SELECT `roles`.* FROM `roles` LIMIT 1
=> "foo"
2.0.0-p247 :021 > test[User.first] = "bar"
User Load (0.3ms) SELECT `users`.* FROM `users` LIMIT 1
=> "bar"
2.0.0-p247 :022 > test[Role.first]
Role Load (0.3ms) SELECT `roles`.* FROM `roles` LIMIT 1
=> "foo"
2.0.0-p247 :023 > test[User.first]
User Load (0.3ms) SELECT `users`.* FROM `users` LIMIT 1
=> "bar"
2.0.0-p247 :024 > Role.first.hash
Role Load (0.3ms) SELECT `roles`.* FROM `roles` LIMIT 1
=> 2650587815033366890
2.0.0-p247 :025 > User.first.hash
User Load (0.5ms) SELECT `users`.* FROM `users` LIMIT 1
=> 2650587815033366890
So in each experiment the hash identifies the right key not by the key object’s hash but by it’s == method.