Reputation: 3974
Consider the following code snippet:
inner_hash =Hash.new
trial_hash = Hash.new
inner_hash.merge!("i_key1"=>"value1")
inner_hash.merge!("i_key2"=>"value2")
puts "inner_hash #{inner_hash}"
trial_hash.merge!("o_key1"=>inner_hash)
puts "trial_hash #{trial_hash}"
inner_hash.clear
inner_hash.merge!("i_key1"=>"value3")
inner_hash.merge!("i_key2"=>"value4")
puts "inner_hash #{inner_hash}"
trial_hash.merge!("o_key2"=>inner_hash)
puts "trial_hash #{trial_hash}"
This is what it prints:
inner_hash {"i_key1"=>"value1", "i_key2"=>"value2"}
trial_hash {"o_key1"=>{"i_key1"=>"value1", "i_key2"=>"value2"}}
inner_hash {"i_key1"=>"value3", "i_key2"=>"value4"}
trial_hash {"o_key1"=>{"i_key1"=>"value3", "i_key2"=>"value4"}, "o_key2"=>{"i_key1"=>"value3", "i_key2"=>"value4"}}
Especially see the trial_hash printed in the last line. The value of key "o_key1" is a hash whose value should have been value1 and value2 but have been overwritten to value3 and value4. ideally the expected output should have been:
inner_hash {"i_key1"=>"value1", "i_key2"=>"value2"}
trial_hash {"o_key1"=>{"i_key1"=>"value1", "i_key2"=>"value2"}}
inner_hash {"i_key1"=>"value3", "i_key2"=>"value4"}
trial_hash {"o_key1"=>{"i_key1"=>"value1", "i_key2"=>"value2"}, "o_key2"=>{"i_key1"=>"value3", "i_key2"=>"value4"}}
Why is this behaviour observed. What wrong am I doing. Originally the question is very broad and uses loops, which for sample purpose here, i have removed and re-written some of the lines. Any help is greatly appreciated. Thanks
EDIT: The problem is solved when I replaced inner_hash.clear with inner_hash={}
Upvotes: 0
Views: 62
Reputation: 122493
When you do:
trial_hash.merge!("o_key1"=>inner_hash)
a reference of inner_hash
is made as the value. So whenever inner_hash
changes, trial_hash["o_key1"]
changes accordingly, because they are references to the same Hash
object.
Check out their object_id
, the same:
trial_hash["o_key1"].object_id
#=> 21676080
trial_hash["o_key2"].object_id
#=> 21676080
inner_hash.object_id
#=> 21676080
You could get your expected behavior if using clone
:
trial_hash.merge!("o_key1"=>inner_hash.clone)
Upvotes: 1