Ruby Quiz – Matricies
October 22nd, 2008 by Radar
nb = 5
distance = Array.new(nb, Array.new(nb))
k = 0
(0...nb).each do |i|
(0...nb).each do |j|
distance[j][i] = k +=1
end
end
puts distance.inspect
This code should generate: [[1,6,11,16,21], [2,7,12,17,22], [3,8,13,18,23], [4,9,13,19,25], [5,10,15,20,25]]
But generates: [[5,10,15,20,25], [5,10,15,20,25], [5,10,15,20,25], [5,10,15,20,25], [5,10,15,20,25]]
I learned why today, and I wonder if anyone else knows.

October 23rd, 2008 at 11:44 am
The problem isnt in the loop, its in the definition of the array. The definition of Array.new in the ruby documentation is:
“Returns a new array. In the first form, the new array is empty. In the second it is created with size copies of obj (that is, size references to the same obj). The third form creates a copy of the array passed as a parameter (the array is generated by calling to_ary on the parameter). In the last form, an array of the given size is created. Each element in this array is calculated by passing the element‘s index to the given block and storing the return value.”
So by doing an Array.new(5, Array.new(5)), you are essentially doing this:
foo = Array.new(5) bar = [foo, foo, foo, foo, foo]
So when ever you change bar[0], you are also changing bar[1], bar[2], etc. etc. because they are the same array.
I hope I explained that correctly, anyway, I fixed it by changing the definition of distance to:
distance = Array.new(nb).map { |o| Array.new }
Which will create a new array with 5 new arrays inside it.
October 23rd, 2008 at 12:52 pm
Keith is correct, well done mate.
October 23rd, 2008 at 1:53 pm
Yay, I win the cheese!
November 25th, 2008 at 7:06 pm
I assumed that the problem must have been somewhere in the loop, rather than in the “setup” code. It’s always the unquestioned assumptions that trip me up.