Forum: Ruby Strange behaviour with array of arrays

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Dan Stevens (IAmAI) (Guest)
on 2007-01-02 23:16
(Received via mailing list)
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.
James G. (Guest)
on 2007-01-02 23:22
(Received via mailing list)
On Jan 2, 2007, at 3:14 PM, Dan Stevens (IAmAI) wrote:

> #Both arrays appear to be equal
> 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 G. II
Tim P. (Guest)
on 2007-01-02 23:24
(Received via mailing list)
On 1/2/07, Dan Stevens (IAmAI) <removed_email_address@domain.invalid> wrote:
> #Both arrays appear to be equal
> 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.
>

The syntax you want is this ...

test2 = Array.new(3) {Array.new(3)}

This will create a new array of three elements and then create a a new
array object for each element of test2

test2 = Array.new(3, Array.new(3))

This will create a new array of three elements but use the same object
for element of test2

Blessings,
TwP
This topic is locked and can not be replied to.