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.
2b4da3f15e2d0f58be623bf40795de07?d=identicon&s=25 Dan Stevens (IAmAI) (Guest)
on 2007-01-02 22: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.
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-01-02 22: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 Gray II
4d5b5dd4e263d780a5dfe7ac8b8ac98c?d=identicon&s=25 Tim Pease (Guest)
on 2007-01-02 22:24
(Received via mailing list)
On 1/2/07, Dan Stevens (IAmAI) <dan.stevens.iamai@gmail.com> 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.