Question

dup is shallow copy, so when doing this:

h = {one: {a:'a', b: 'b'}}
h_copy = h.dup
h_copy[:one][:b] = 'new b'

now h and h_copy is same: {:one=>{:a=>"a", :b=>"new b"}} yes, that right.

But when h is a one dimension hash:

h = {a:'a', b: 'b'}
h_copy = h.dup
h_copy[:b] = 'new b'
h still is: {a:'a', b: 'b'}
h_copy is {a:'a', b: 'new b'}

Why?

Was it helpful?

Solution 3

So after 1 hour of brainstorming..I have come to the conclusion that in the multi dimensional hashes, the dup generates the same object_id for each key which is in turn referring to the hash whereas in the single dimensional hash, the object_ids are similar initially but when we make any changes to the object the Ruby would assign new object_id to the hash keys..

Look at the following code

h = { :a => "a", :b => "b" } # => {:a=>"a", :b=>"b"} 
h_clone = h.dup #=> {:a=>"a", :b=>"b"} 
h.object_id #=> 73436330 
h_clone.object_id #=> 73295920 
h[:a].object_id #=> 73436400 
h_clone[:a].object_id #=> 73436400 
h[:b].object_id #=> 73436380 
h_clone[:b].object_id #=> 73436380 
h_clone[:b] = "New B" #=> "New B" 
h_clone[:b].object_id #=> 74385280 
h.object_id #=> 73436330 
h_clone.object_id #=> 73295920 
h[:a].object_id #=> 73436400 
h_clone[:a].object_id #=> 73436400

Look the following code for the multidimensional array

h = { :one => { :a => "a", :b => "b" } } #=> {:one=>{:a=>"a", :b=>"b"}} 
h_copy = h.dup #=> {:one=>{:a=>"a", :b=>"b"}} 
h_copy.object_id #=> 80410620 
h.object_id #=> 80552610 
h[:one].object_id #=> 80552620 
h_copy[:one].object_id #=> 80552620 
h[:one][:a].object_id #=> 80552740 
h_copy[:one][:a].object_id #=> 80552740 
h[:one][:b].object_id #=> 80552700 
h_copy[:one][:b].object_id #=> 80552700 
h_copy[:one][:b] = "New B" #=> "New B" 
h_copy #=> {:one=>{:a=>"a", :b=>"New B"}} 
h #=> {:one=>{:a=>"a", :b=>"New B"}} 
h.object_id #=> 80552610 
h_copy.object_id #=> 80410620 
h[:one].object_id #=> 80552620 
h_copy[:one].object_id #=> 80552620 
h[:one][:b].object_id #=> 81558770 
h_copy[:one][:b].object_id #=> 81558770

OTHER TIPS

You can think about your two-dimensional hash as some kind of container, which conatins another hash container. So you have 2 containers.

When you call dup on h, then dup returns you copy of your outermost container, but any inner containers are not copied, so this is what shallow copy does. Now after dup you have 3 containers: h_copy is your new third container, which :one key just points to h's inner container

As you said, dup is shallow copy.

It appears you want both h_copy and h to refer to the same object.

Then simply do h_copy = h (i.e. no dup).

h = {a:'a', b: 'b'}
h_copy = h.dup
h_copy[:b] = 'new b'
h #=> {a:'a', b: 'new b'}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top