# Array funkiness?

**URL:** <https://www.ruby-forum.com/t/array-funkiness/85851>\
**Category:** Ruby\
**Created:** [February 16, 2007, 8:01pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851 "2007-02-16T20:01:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 16, 2007, 8:01pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/1 "2007-02-16T20:01:49Z")

</div>

When trying to append to an array that lives in an array, it appends  
to all until the individual array is used with =

Here’s exactly what I did

irb(main):007:0\> a=Array.new(9,Array.new())  
I expect and I get [[], [], [], [], [], [], [], [], []]

irb(main):008:0\> a[0]\<\<1  
I expect [[1], [], [], [], [], [], [], [], []]  
but I get [[1], [1], [1], [1], [1], [1], [1], [1], [1]]

irb(main):009:0\> a[0]\<\<1  
I expect [[1,1], [], [], [], [], [], [], [], []]  
but I get [[1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1,  
1], [1, 1]]

irb(main):010:0\> a[0]=[1,2,3]  
I expect [[1,2,3], [], [], [], [], [], [], [], []]  
but I get [[1,2,3], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1],  
[1, 1], [1, 1]]

So once more  
irb(main):011:0\> a[0]\<\<1  
originally I would have expected  
I expect [[1,2,3,1], [], [], [], [], [], [], [], []]  
now because of this wacky behavior I expect  
[[1, 2, 3, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1],  
[1, 1,1], [1, 1, 1], [1, 1, 1]]  
but what actually happens? This  
[[1, 2, 3, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1],  
[1, 1]]

What on earth is happening?

–Kyle

PS: I do have a work around so my code works as I expected it, using  
+=[i] instead of \<\<i, but I really want to know _why_ here.

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 16, 2007, 8:29pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/2 "2007-02-16T20:29:52Z")

</div>

Ahh. Any clue as to what the rational on making Array.new work that was  
was?  
I can think of situations where I’d want to use the same object over  
and over, but more situations where I’d want a new object in each one.

Thanks alot!  
–Kyle

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 16, 2007, 8:20pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/3 "2007-02-16T20:20:51Z")

</div>

On Feb 16, 12:01 pm, “Kyle S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> but I get [[1], [1], [1], [1], [1], [1], [1], [1], [1]]  
> The short answer is “RTFM” - type in  
> ri Array.new  
> in your console and you’ll see all this described.

The nice longer answer follows.

You basically asked Ruby to do:  
b = Array.new  
a = [b,b,b,b,b,b,b,b,b]  
so modifying any particular instance modifies them all.

What you wanted was:  
irb(main):001:0\> a = Array.new(9){ Array.new }  
=\> [[], [], [], [], [], [], [], [], []]  
irb(main):002:0\> a[0] \<\< 1  
=\> [1]  
irb(main):003:0\> a  
=\> [[1], [], [], [], [], [], [], [], []]

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 16, 2007, 8:31pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/4 "2007-02-16T20:31:52Z")

</div>

Kyle S. wrote:

> When trying to append to an array that lives in an array, it appends  
> to all until the individual array is used with =
> 
> Here’s exactly what I did
> 
> irb(main):007:0\> a=Array.new(9,Array.new())  
> I expect and I get [[], [], [], [], [], [], [], [], []]

You probably also expect those nine arrows to be nine different empty  
arrays  
(the result of calling Array.new nine times), but that is not the case.  
Array.new is called exactly once and a[0] to a[8] point to the empty  
array  
resulting from that.  
So naturally if you change one of the arrays, you change them all,  
because  
they’re all the same array.  
If you however replace one of the arrays with another array, the rest  
aren’t  
affected.  
I hope I explained this right and helped you understand.

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 16, 2007, 8:55pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/5 "2007-02-16T20:55:02Z")

</div>

On 2/16/07, Kyle S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Ahh. Any clue as to what the rational on making Array.new work that was was?  
> I can think of situations where I’d want to use the same object over  
> and over, but more situations where I’d want a new object in each one.

Yes.

bitvector = Array.new(32, 0)

If you need complex handling, as others have pointed out, use the block  
form.

-austin

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 17, 2007, 12:50am UTC](https://www.ruby-forum.com/t/array-funkiness/85851/6 "2007-02-17T00:50:28Z")

</div>

“Kyle S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

> Ahh. Any clue as to what the rational on making Array.new work that was  
> was?  
> I can think of situations where I’d want to use the same object over  
> and over, but more situations where I’d want a new object in each one.

```
Yes, because the other way isn't really possible. Think about it.

```

You’re asking the array class to take the second parameter and… do  
what  
with it, exactly? Call the .dup method on it? That requires you to  
needlessly assume the object has defined that method, an assumption we’d  
rather not make if we didn’t have to…  
The way it is now, it’s very natural to use the second parameter to  
reference that object multiple times. Furthermore, the block naturally  
performs whatever code that block does for each element, like iterators.  
Thus, duplication is natural…  
If you read the manual, you’ll see that this really is the better  
interface…

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [February 17, 2007, 12:13pm UTC](https://www.ruby-forum.com/t/array-funkiness/85851/7 "2007-02-17T12:13:09Z")

</div>

On 2/17/07, Phrogz [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> You basically asked Ruby to do:  
> b = Array.new  
> a = [b,b,b,b,b,b,b,b,b]  
> so modifying any particular instance modifies them all.

And the reason a[0] += [i] works is that internally it gets converted  
to a[0] = a[0] + i, so that it returns a different object altogether.

martin
