четвер, 11 жовтня 2012 р.

Creating an array of hashes in ruby



Learning Ruby I've found out one interesting thing and I believe it would be good to share this with another newbies in Ruby. 
I've made a simple mistake in my code and spent about 2 hours debugging it. Maybe it's a well know "issue" for ruby developers, but not for beginners. Ok. In the following code, I wanted to create an array of hashes with some "whatever" data:


vertices = Hash.new
incidentVertices = Array.new() 
(0..2).each do  |x|
  (0..2).each { |y|  vertices[x+y] = x+y }
  incidentVertices.push(vertices)
end
puts incidentVertices

From my point of view, it should have returned the following:

{0=>0, 1=>1, 2=>2}
{1=>1, 2=>2, 3=>3}
{2=>2, 3=>3, 4=>4}

Was I right? No, I was not. The right output is as following:

{0=>0, 1=>1, 2=>2, 3=>3, 4=>4}
{0=>0, 1=>1, 2=>2, 3=>3, 4=>4}
{0=>0, 1=>1, 2=>2, 3=>3, 4=>4}


The Hash.new creates only one hash and then each element in the array contains "pointers" to the same hash, so when any value is changed, all are changed.

Moving the hash creation line inside the loop fixes everything:

incidentVertices = Array.new() 
(0..2).each do |x|
  vertices = Hash.new
  (0..2).each { |y| vertices[x+y] = x+y }
  incidentVertices.push(vertices)
end
puts incidentVertices


:wq