Home > Blockchain >  Why does Ruby keep the relationship to a hash when initializing with variable?
Why does Ruby keep the relationship to a hash when initializing with variable?

Time:06-10

maybe I am used to the initialState from React, but I tried doing something similar in Ruby and I noticed it updates the hash everywhere I initialized it.

Here's an example:

iniatializing_hash = {likes_count: 0, comments_count: 0}
hash_that_uses_initializer = {first: iniatializing_hash, second: iniatializing_hash}

# update first
hash_that_uses_initializer[:first][:likes_count]  = 1
hash_that_uses_initializer[:first][:comments_count]  = 1

# expect both first and second were updated
puts "first: #{hash_that_uses_initializer[:first].inspect} and second: #{hash_that_uses_initializer[:second].inspect}"
# returns first: {:likes_count=>1, :comments_count=>1} and second: {:likes_count=>1, :comments_count=>1}

I'm guessing this happens because it keeps the connection to the place in memory the hash is loaded.

Is there another elegant way to use an 'initialState' hash in Ruby?

Thanks!

CodePudding user response:

Hashes are passed by reference. When you assign iniatializing_hash, it does not assign a copy of the hash - it assigns a pointer. When you change the values of the hash that you assigned to :first, you're also changing the values of the hash at :second because they're both the same hash.

You can prove they're the same location in memory by calling object_id method on the object:

echo('same hash') if iniatializing_hash.object_id == hash_that_uses_initializer[:first].object_id == hash_that_uses_initializer[:second].object_id

If you want a copy, then you need a deep copy.

def deep_copy(initial_hash)
  Marshal.load(Marshal.dump(o))
end

hash_that_uses_initializer = {first: deep_copy(iniatializing_hash), second: deep_copy(iniatializing_hash)}

Now the hash stored at :first and the :second will be completely different from each other and different from iniatializing_hash

  • Related