Home > Back-end >  Understanding how hash copy is behaving under the hood
Understanding how hash copy is behaving under the hood

Time:12-22

I came out with an example of ruby hashes that I cannot quite understand what is happening under the hood:

root = {}
base = root
base[:a] = {}
base = base[:a]
p base
=> {}
p root
=> {:a=>{}}

When I assign base = base[:a] as I was expecting base becomes {}, but why root doesn't become {} too?

CodePudding user response:

I just needed a little push to understand, and thanks to @Stefan I think I can answer my own question. Breaking it down we have:

root = {}
base = root
puts root.object_id
=> 47193371579760
puts base.object_id
=> 47193371579760

So both root and base became a reference for the same object.

base[:a] = {}
base[:a].object_id
=> 47193372751820
base = base[:a]
puts base.object_id
=> 47193372751820
puts root.object_id
=> 47193371579760
puts root

base[:a] is a new hash object, and base assigned to it becomes this object while root keeps the reference for the old object that was assigned {:a=>{}}. That's why root doesn't change at the end.

CodePudding user response:

Array, Symbol and Hash are some reference variables. Similar concept is present in all language. Taking example of javascript, we can relate same with concept of shallow copy & deep copy where hash is replaced by object.

Following is little explanation added for your query.

root = {}
# root = {}
base = root
# both base & root variables point to single location, principle of reference object
base[:a] = {}
# base aka root variable is holding value { a: {} }
base = base[:a]
# base variable is not pointing to root variable location, it is re-assigned with new value which is also hash (reference object)

p base
=> {}
p root
=> {:a=>{}}
base[:b] = 4
=> 4
p base
=> {:b=>4} 
p root
=> {:a=>{:b=>4}} 

Using object_id function you can verify address. To make deep copy use clone function for hash.

  •  Tags:  
  • ruby
  • Related