On Jan 2, 2007, at 3:14 PM, Dan Stevens (IAmAI) wrote:

> Please observe the following code:
>
> # Create an array of arrays by explicitly stating values
> test1 = [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
> => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
>
> # Create an array of arrays using new method
> test2 = Array.new(3, Array.new(3))
> => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
>
> #Both arrays appear to be equal
> test1 == test2 => true
>
> # Modifying one of values behaves as expected
> test1[1][1] = true => true
> test1 => [[nil, nil, nil], [nil, true, nil], [nil, nil, nil]]
>
> # Modifying one of values behaves strangely
> test2[1][1] = true => true
> test2 => [[nil, true, nil], [nil, true, nil], [nil, true, nil]]
>
> Can anyone explain why this is happening as I don't understand why the
> two array should behave differently? This is assuming this isn't a
> bug.

Let me see if I can get Ruby to explain this for you:

 >> a = [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
 >> a.map { |e| e.object_id }
=> [3797062, 3797052, 3797042]
 >> a = Array.new(3, Array.new(3))
=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
 >> a.map { |e| e.object_id }
=> [3779002, 3779002, 3779002]
 >> a = Array.new(3) { Array.new(3) }
=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
 >> a.map { |e| e.object_id }
=> [3760242, 3760232, 3760222]

As you can see, the new(n, obj) constructor uses the same object over  
and over again.  You want the block form (shown last) instead.

James Edward Gray II