# 3x3 Array of int, changing one value affects others

**URL:** <https://www.ruby-forum.com/t/3x3-array-of-int-changing-one-value-affects-others/195692>\
**Category:** Ruby\
**Created:** [September 28, 2010, 10:46am UTC](https://www.ruby-forum.com/t/3x3-array-of-int-changing-one-value-affects-others/195692 "2010-09-28T10:46:59Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![williams](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/f1d935/32.png) [@williams](https://www.ruby-forum.com/u/williams)\
**Post date:** [September 28, 2010, 10:46am UTC](https://www.ruby-forum.com/t/3x3-array-of-int-changing-one-value-affects-others/195692/1 "2010-09-28T10:46:59Z")

</div>

ruby-1.9.2-head \> a = Array.new(3, Array.new(3, 0))  
=\> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  
ruby-1.9.2-head \> a[0][2] = 1  
=\> 1  
ruby-1.9.2-head \> a  
=\> [[0, 0, 1], [0, 0, 1], [0, 0, 1]]

If the values aren’t all 0s, a[0][2] behaves correctly. Am I doing  
something wrong? Thanks.

---

<div class="post-metadata">

**Author:** ![williams](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/f1d935/32.png) [@williams](https://www.ruby-forum.com/u/williams)\
**Post date:** [September 28, 2010, 11:02am UTC](https://www.ruby-forum.com/t/3x3-array-of-int-changing-one-value-affects-others/195692/2 "2010-09-28T11:02:10Z")

</div>

On Tue, Sep 28, 2010 at 10:47 AM, Williams Williams  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ruby-1.9.2-head \> a = Array.new(3, Array.new(3, 0))  
> =\> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  
> ruby-1.9.2-head \> a[0][2] = 1  
> =\> 1  
> ruby-1.9.2-head \> a  
> =\> [[0, 0, 1], [0, 0, 1], [0, 0, 1]]
> 
> If the values aren’t all 0s, a[0][2] behaves correctly. Am I doing  
> something wrong? Thanks.

That constructor of Array takes the second argument, and places it  
(the same object) in all positions of the array.  
So when you modify that object, you see the modification in all  
positions. If you want a different object in each position, try the  
block form:

irb(main):001:0\> a = Array.new(3,Array.new(3,0))  
=\> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  
irb(main):002:0\> a[0].object\_id  
=\> -609376368  
irb(main):003:0\> a[1].object\_id  
=\> -609376368  
irb(main):004:0\> a[2].object\_id  
=\> -609376368

# Same object id

irb(main):005:0\> a = Array.new(3) {Array.new(3,0)}  
=\> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  
irb(main):006:0\> a[0].object\_id  
=\> -609423628  
irb(main):007:0\> a[1].object\_id  
=\> -609423638  
irb(main):010:0\> a[2].object\_id  
=\> -609423678

# different object id

Jesus.

---

<div class="post-metadata">

**Author:** ![williams](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/f1d935/32.png) [@williams](https://www.ruby-forum.com/u/williams)\
**Post date:** [September 28, 2010, 11:06am UTC](https://www.ruby-forum.com/t/3x3-array-of-int-changing-one-value-affects-others/195692/3 "2010-09-28T11:06:16Z")

</div>

On Tuesday 28 September 2010, Williams Williams wrote:

> |ruby-1.9.2-head \> a = Array.new(3, Array.new(3, 0))  
> | =\> [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  
> |ruby-1.9.2-head \> a[0][2] = 1  
> | =\> 1  
> |ruby-1.9.2-head \> a  
> | =\> [[0, 0, 1], [0, 0, 1], [0, 0, 1]]  
> |  
> |If the values aren’t all 0s, a[0][2] behaves correctly. Am I doing  
> |something wrong? Thanks.

Array.new(size, obj) doesn’t work the way you think. It creates an array  
with  
size elements, where each element is the _same object_. By same object,  
I  
don’t mean different objects equal to each other, but one single object  
(you  
can see this looking at the object\_id of the sub-arrays). So, it should  
be no  
wonder that modifying one of the elements also changes the others. If  
you want  
to create an array containing three different arrays [0,0,0], you need  
to use  
the block form of Array.new:

Array.new(3){|i| Array.new(3,0)}

This constructor creates an array of the given size, then calls the  
block for  
each index of the array and stores in that index the value returned by  
the  
block. Different from your code, now the array contains three arrays  
with  
different identities, all with the same contents. This is because every  
time  
the block is called, it returns a new array.

To be more clear, your code has the same results as:

# create an array of size 3 filled with nil

a = Array.new(3)

# create the subarray

subarray = Array.new(3,0)  
#store the same subarray in all the three entries of the array  
a[0] = subarray  
a[1] = subarray  
a[2] = subarray

The code which works as you want, instead, produces the same as:

# create an array of size 3 filled with nil

a = Array.new(3)  
#store in the tree entries of the array three different arrays with  
#the same contents  
a[0] = Array.new(3,0)  
a[1] = Array.new(3,0)  
a[2] = Array.new(3,0)

Usually, you only use Array.new(size, obj) when obj is an immutable  
object,  
that is an object with no methods which modify it. Your use of  
Array.new(3,0),  
for instance, is correct because an Integer can’t be modified. The same  
would  
be true, for example, for symbols. If obj is a mutable object, like a  
string,  
an array or a hash (which all have methods which change the object  
itself),  
creating an array this way can lead to unexpected result, as you have  
experienced yourself.

I hope this helps

Stefano
