Vovanches Vovanches - 2 months ago 8
Ruby Question

How to break links between created objects

I want to make a hash of arrays.

If I do this:

res = Hash[(1..5).zip Array.new(5, [])]


I will get this as result:

{1=>[], 2=>[], 3=>[], 4=>[], 5=>[]}


It's ok. But, when I try to change one of this array, Ruby changes them all, and that is not OK.

If I do this:

res[1] << 1


I will get this as result:

{1=>[1], 2=>[1], 3=>[1], 4=>[1], 5=>[1]}


I was trying to use other variants, like:

res = Hash[(1..5).zip Array.new(5, Array.new)]
res = Hash[(1..5).zip Array.new(5, [].dup)]
res = Hash[(1..5).zip Array.new(5, [].clone)]
res = Hash[(1..5).zip Array.new(5, []).clone]


But they gave me the same result.

Why?

Answer

Pass a block into the Array.new method to get elements with different object IDs. Each array is a different object:

res = Hash[(1..5).zip(Array.new(n){[]})]
Comments