Dan Rubio Dan Rubio - 3 months ago 11
Ruby Question

Why does this code populate every array?

I have this piece of code that creates an array of arrays (

[[],[],[]]
) and an iterator that attempts to populate the respective arrays with numbers (shown below)

array = Array.new(3,[])
10.times do
array[0] << 2
array[1] << 3
array[2] << 4
end


When I execute this code, I expected to see this

[[2,2,2,2,etc....],[3,3,3,3,etc...],[4,4,4,4,4...etc]]


but instead I get this:

[[2,3,4,2,3,4,2,3,4....repeat],[2,3,4,2,3,4,2,3,4....repeat],[2,3,4,2,3,4,2,3,4....repeat]]


I've tried to walk through it with
byebug
and it makes no sense to me. What is going on here?

Answer

Array.new(3, []) is not equivalent to [[],[],[]]. It is equivalent to array = []; [array, array, array], an array of three references to the same array. After array[0] << 2, you have [[2], [2], [2]], because all three elements point at the same array.

What you want is Array.new(3) { [] }, with a block specifying the default; this way, a new [] is created for each element.

Even better, your whole code can be written as:

Array.new(3) { |i| Array.new(10, i + 2) }
Comments