Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Properties of a hash key

Tags:

ruby

I will just paste down a simple example i tried so that it would be clear to those who read this.

irb(main):001:0> h =  { }
=> {}
irb(main):002:0> a=[1,2,3]
=> [1, 2, 3]
irb(main):003:0> a.object_id
=> 69922343540500


irb(main):004:0> h[a] = 12          #Hash with the array as a key
=> 12
irb(main):005:0> a << 4             #Modified the array
=> [1, 2, 3, 4]
irb(main):006:0> a.object_id        #Object id obviously remains the same.
=> 69922343540500
irb(main):007:0> h[a]               #Hash with the same object_id now returns nil.
=> nil
irb(main):008:0> h                  #Modified hash
=> {[1, 2, 3, 4]=>12}
irb(main):009:0> h[[1,2,3,4]]       #Tried to access the value with the modified key -
=> nil


irb(main):011:0> h.each { |key,value| puts "#{key.inspect} maps #{value}" }
[1, 2, 3, 4] maps 12
=> {[1, 2, 3, 4]=>12}

Now when i iterate over the hash, its possible to identify the map between the key and the value.

Could some one please explain me this behaviour of ruby hash and what are the properties of hash keys.

1) As i mentioned above, the object_id hasn't changed - then why is the value set to nil.

2) Is there any possible way so that i can get back the value '12' from the hash 'h' because h[[1,2,3,4]] as mentioned above returns nil.

like image 941
Sunil Avatar asked Dec 22 '22 11:12

Sunil


2 Answers

This happens because the key should not have its value changed while it is in use. If the value changes, we should rebuild the hash, based on its current value. Look at Ruby API for rehash method. You can get back the value, by rebuilding the hash again after the key is changed, like this:

irb(main):022:0> h.rehash
=> {[1, 2, 3, 4]=>12}
irb(main):023:0> h[a]
=> 12
like image 182
rubyprince Avatar answered Jan 19 '23 19:01

rubyprince


Hash keys are checked using the #eql? method, and since [1, 2, 3] isn't .eql? to [1, 2, 3,4] your hash lookup has a different result.

Maybe you want to be using something other than an Array as your Hash key if the semantics aren't working for you?

like image 41
Gareth Avatar answered Jan 19 '23 18:01

Gareth