1

I have one Array.

arr = []

I have one Hash

hash = {a: 1, b: 2, c: 3}

Addind hash in Array

arr << hash

value of arr is:

[{:a=>1, :b=>2, :c=>3}] 

Now Adding value in Hash

hash[:d] = 4

Now See Value of Array is:

[{:a=>1, :b=>2, :c=>3, :d=>4}]

Can anyone please explain to me about this. as this is a little confusing. Thank in Advance.

Ketan Mangukiya
  • 360
  • 1
  • 7
  • 1
    Adding to `arr` doesn't copy hash and create a new object. It adds the actual `hash` object to `arr`. So any changes to `hash` will affect where ever it sits. – Harry Bomrah Dec 06 '19 at 05:58
  • Assuming that there will be single hash in the arr, following code will serve your purpose: arr[0].merge!(d: 4) – Rohan Dec 06 '19 at 06:01
  • Or do not add the hash into the array, instead, add a duplicate to the array: `arr << hash.dup` – spickermann Dec 06 '19 at 06:23

2 Answers2

1

Because hash inside the array also has the same object_id, let's try it with an example

2.6.3 :008 > arr = []
 #=> [] 
2.6.3 :009 > hash = {a: 1, b: 2, c: 3}
 #=> {:a=>1, :b=>2, :c=>3} 
2.6.3 :010 > arr << hash
 #=> [{:a=>1, :b=>2, :c=>3}] 
2.6.3 :011 > arr.first.object_id
 #=> 70240020878720 
2.6.3 :012 > hash.object_id
 #=> 70240020878720

As you can see, arr.first.object_id and hash.object_id both have same object_id therefore any changes you make in hash will also be reflected in hash inside arr because it's the same object.

Now if you don't want to see that behavior then create a new object instead, use dup, try this

2.6.3 :001 > arr = []
 #=> [] 
2.6.3 :002 > hash = {a: 1, b: 2, c: 3}
 #=> {:a=>1, :b=>2, :c=>3} 
2.6.3 :003 > arr << hash.dup
 #=> [{:a=>1, :b=>2, :c=>3}] 
2.6.3 :004 > arr.first.object_id
 #=> 70094898530860 
2.6.3 :005 > hash.object_id
 #=> 70094898418620 
2.6.3 :006 > hash[:d] = 4
 #=> 4 
2.6.3 :007 > arr
 #=> [{:a=>1, :b=>2, :c=>3}] 
2.6.3 :008 > hash
 #=> {:a=>1, :b=>2, :c=>3, :d=>4} 

dup creates a new object and hence you won't see the changes made in both the places because both are different object with different object_id

Hope that helps!

Rajdeep Singh
  • 17,621
  • 6
  • 53
  • 78
0

When we consider enumerable data like array or hash, it works by providing reference,

you can read in brief HERE,

and you can have simple example as below,

ar1 = [23]
# => [23] 
ar2 = ar1
# => [23] 
ar2 << 34
# => [23, 34] 
ar1
# => [23, 34] 

You can avoid this behaviour by creating new object by new keyword rather than passing reference of existing enumerable object.

ray
  • 5,454
  • 1
  • 18
  • 40