# Array::new

**URL:** <https://rubytalk.org/t/array-new/17871>\
**Category:** ruby-talk\
**Created:** [25 April 2005 12:36 UTC](https://rubytalk.org/t/array-new/17871 "2005-04-25T12:36:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jamie\_Hodkinson](https://avatars.discourse-cdn.com/v4/letter/j/e9a140/32.png) [@Jamie\_Hodkinson](https://rubytalk.org/u/Jamie_Hodkinson)\
**Post date:** [25 April 2005 12:36 UTC](https://rubytalk.org/t/array-new/17871/1 "2005-04-25T12:36:11Z")

</div>

Just had something unexpected - is this the correct behaviour?

foo = Array.new(3,Array.new)  
foo[0] \<\< 4  
foo[1] \<\< 5  
foo[0] \<\< 6  
p foo

outputs...

[[4, 5, 6], [4, 5, 6], [4, 5, 6]]

I realise what's happening here, and might have expected it if the  
first line was  
foo = Array.new(3,[])

I'm left with doing this:  
foo = (1..3).collect { [] }

which doesn't exactly raise my heartbeat. Any other options?

Cheers

Jamie

---

<div class="post-metadata">

**Author:** ![Dave\_Baldwin](https://avatars.discourse-cdn.com/v4/letter/d/e95f7d/32.png) [@Dave\_Baldwin](https://rubytalk.org/u/Dave_Baldwin)\
**Post date:** [25 April 2005 12:46 UTC](https://rubytalk.org/t/array-new/17871/2 "2005-04-25T12:46:02Z")

</div>

> Just had something unexpected - is this the correct behaviour?
> 
> foo = Array.new(3,Array.new)  
> foo[0] \<\< 4  
> foo[1] \<\< 5  
> foo[0] \<\< 6  
> p foo
> 
> outputs...
> 
> [[4, 5, 6], [4, 5, 6], [4, 5, 6]]
> 
> I realise what's happening here, and might have expected it if the  
> first line was  
> foo = Array.new(3,)
> 
> I'm left with doing this:  
> foo = (1..3).collect { }
> 
> which doesn't exactly raise my heartbeat. Any other options?

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

gives you what you want.

Dave.

> **···**
>
> On 25 Apr 2005, at 13:36, Jamie Hodkinson wrote:
> 
> > Cheers
> > 
> > Jamie

---

<div class="post-metadata">

**Author:** ![Adriano\_Ferreira](https://avatars.discourse-cdn.com/v4/letter/a/a3d4f5/32.png) [@Adriano\_Ferreira](https://rubytalk.org/u/Adriano_Ferreira)\
**Post date:** [25 April 2005 12:53 UTC](https://rubytalk.org/t/array-new/17871/3 "2005-04-25T12:53:18Z")

</div>

> foo = Array.new(3,Array.new)  
> foo = Array.new(3,)

I think these are just the same. Indeed, the object creation ( or  
Array.new) happens only once. To have distinct arrays in every slot of  
foo you need something like

foo = Array.new(3) { Array.new }  
foo[0] \<\< 4  
foo[1] \<\< 5  
foo[0] \<\< 6  
p foo

(as Dave Baldwin suggested) and you'll get

[[4, 6], [5], ]

If you come to this code, by looking at the Array documentation where  
the example  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.new(2, Hash.new) » [{}, {}]  
is given, I agree that this documentation is misleading for beginners.

Regards,  
Adriano.

---

<div class="post-metadata">

**Author:** ![Jamie\_Hodkinson](https://avatars.discourse-cdn.com/v4/letter/j/e9a140/32.png) [@Jamie\_Hodkinson](https://rubytalk.org/u/Jamie_Hodkinson)\
**Post date:** [25 April 2005 12:51 UTC](https://rubytalk.org/t/array-new/17871/4 "2005-04-25T12:51:10Z")

</div>

Brilliant, thank you.

> **···**
>
> On 4/25/05, Dave Baldwin \<dave.baldwin@3dlabs.com\> wrote:
> 
> > On 25 Apr 2005, at 13:36, Jamie Hodkinson wrote:
> > 
> > \> Just had something unexpected - is this the correct behaviour?  
> > \>  
> > \> foo = Array.new(3,Array.new)  
> > \> foo[0] \<\< 4  
> > \> foo[1] \<\< 5  
> > \> foo[0] \<\< 6  
> > \> p foo  
> > \>  
> > \> outputs...  
> > \>  
> > \> [[4, 5, 6], [4, 5, 6], [4, 5, 6]]  
> > \>  
> > \> I realise what's happening here, and might have expected it if the  
> > \> first line was  
> > \> foo = Array.new(3,)  
> > \>  
> > \> I'm left with doing this:  
> > \> foo = (1..3).collect { }  
> > \>  
> > \> which doesn't exactly raise my heartbeat. Any other options?  
> > \>
> > 
> > foo = Array.new(3){Array.new}
> > 
> > gives you what you want.
> > 
> > Dave.
> > 
> > \> Cheers  
> > \>  
> > \> Jamie  
> > \>

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [25 April 2005 14:09 UTC](https://rubytalk.org/t/array-new/17871/5 "2005-04-25T14:09:29Z")

</div>

"Adriano Ferreira" \<a.r.ferreira@gmail.com\> schrieb im Newsbeitrag  
news:73ddeb6c0504250552da67f6@mail.gmail.com...

> \> foo = Array.new(3,Array.new)  
> \> foo = Array.new(3,)
> 
> I think these are just the same.

Nearly: with Array.new you cannot provide a list of values like with -  
but apart from that: yes, "" is syntactical sugar for "Array.new"  
followed by some element additions.

> Indeed, the object creation ( or  
> Array.new) happens only once.

That's the crucial part to understand: "" or "Array.new" is an argument  
to a method invocation (Array.new) so it's evaluated \*once before\* the  
method is invoked and the second parameter is bound to this value.  
Perfectly logical and reasonable.

> To have distinct arrays in every slot of  
> foo you need something like
> 
> foo = Array.new(3) { Array.new }  
> foo[0] \<\< 4  
> foo[1] \<\< 5  
> foo[0] \<\< 6  
> p foo
> 
> (as Dave Baldwin suggested) and you'll get
> 
> [[4, 6], [5], ]
> 
> If you come to this code, by looking at the Array documentation where  
> the example  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.new(2, Hash.new) » [{}, {}]  
> is given, I agree that this documentation is misleading for beginners.

Yep, true. Probably a better example would be

> > Array.new(2, {"foo"=\>"bar"})

=\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<div class="post-metadata">

**Author:** ![Gavin\_Kistner2](https://avatars.discourse-cdn.com/v4/letter/g/b9e5f3/32.png) [@Gavin\_Kistner2](https://rubytalk.org/u/Gavin_Kistner2)\
**Post date:** [25 April 2005 14:22 UTC](https://rubytalk.org/t/array-new/17871/6 "2005-04-25T14:22:53Z")

</div>

Though even then, it would appear (to someone wanting the specific functionality of the OP, and probably 'most' cases) that the parameter is used as a template, with .dup used for each instance. I think the example should illustrate that the objects are in fact the same, and discuss the end result each has:

my\_array = Array.new( 2, { :foo =\> :bar } )  
my\_array[1][:jimmy] = :jammy  
p my\_array  
#=\> [{:foo=\>:bar, :jimmy=\>:jammy}, {:foo=\>:bar, :jimmy=\>:jammy}]

my\_array = Array.new( 2 ){ { :foo =\> :bar } }  
my\_array[1][:jimmy] = :jammy  
p my\_array  
#=\> [{:foo=\>:bar}, {:foo=\>:bar, :jimmy=\>:jammy}]

> **···**
>
> On Apr 25, 2005, at 8:09 AM, Robert Klemme wrote:
> 
> > > If you come to this code, by looking at the Array documentation where  
> > > the example  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.new(2, Hash.new) » [{}, {}]  
> > > is given, I agree that this documentation is misleading for beginners.
> > 
> > Yep, true. Probably a better example would be
> > 
> > > > Array.new(2, {"foo"=\>"bar"})
> > 
> > =\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [25 April 2005 14:44 UTC](https://rubytalk.org/t/array-new/17871/7 "2005-04-25T14:44:28Z")

</div>

"Gavin Kistner" \<gavin@refinery.com\> schrieb im Newsbeitrag  
news:b3bc6362698d8da96cf5b6d43cb334f1@refinery.com...

> \>\> If you come to this code, by looking at the Array documentation where  
> \>\> the example  
> \>\> Array.new(2, Hash.new) » [{}, {}]  
> \>\> is given, I agree that this documentation is misleading for

beginners.

> \>  
> \> Yep, true. Probably a better example would be  
> \>  
> \>\>\> Array.new(2, {"foo"=\>"bar"})  
> \> =\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]
> 
> Though even then, it would appear (to someone wanting the specific  
> functionality of the OP, and probably 'most' cases) that the parameter  
> is used as a template, with .dup used for each instance.

Probably.

> I think the  
> example should illustrate that the objects are in fact the same, and  
> discuss the end result each has:
> 
> my\_array = Array.new( 2, { :foo =\> :bar } )  
> my\_array[1][:jimmy] = :jammy  
> p my\_array  
> #=\> [{:foo=\>:bar, :jimmy=\>:jammy}, {:foo=\>:bar, :jimmy=\>:jammy}]
> 
> my\_array = Array.new( 2 ){ { :foo =\> :bar } }  
> my\_array[1][:jimmy] = :jammy  
> p my\_array  
> #=\> [{:foo=\>:bar}, {:foo=\>:bar, :jimmy=\>:jammy}]

Nice, too. Or do

> > a = Array.new(2, {"foo"=\>"bar"})

=\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]

> > a.map{|o| o.object\_id}

=\> [135028744, 135028744]

> > a.map{|o| o.object\_id}.uniq

=\> [135028744]

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

> **···**
>
> > On Apr 25, 2005, at 8:09 AM, Robert Klemme wrote:

---

<div class="post-metadata">

**Author:** ![Dmitriy\_Genzel](https://avatars.discourse-cdn.com/v4/letter/d/a88e4f/32.png) [@Dmitriy\_Genzel](https://rubytalk.org/u/Dmitriy_Genzel)\
**Post date:** [25 April 2005 20:44 UTC](https://rubytalk.org/t/array-new/17871/8 "2005-04-25T20:44:27Z")

</div>

Better yet, I think Array.new in the -w mode should check if it got called with a second argument that responds to "each" or  
perhaps to "=" and warn. I can't think of any meaningful use for Array.new(n, Array.new) or of any use where a container is given  
as a default argument of an array in such a manner.

And the same should apply to Hash.new.

Just about any newbie (especially with Perl background) runs into this, I think. I know I did.

Dmitriy

> **···**
>
> On Apr 25, 2005, at 10:44 AM, Robert Klemme wrote:
> 
> > "Gavin Kistner" \<gavin@refinery.com\> schrieb im Newsbeitrag  
> > news:b3bc6362698d8da96cf5b6d43cb334f1@refinery.com...
> > 
> > > On Apr 25, 2005, at 8:09 AM, Robert Klemme wrote:
> > > 
> > > > > If you come to this code, by looking at the Array documentation where  
> > > > > the example  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.new(2, Hash.new) » [{}, {}]  
> > > > > is given, I agree that this documentation is misleading for
> > 
> > beginners.
> > 
> > > > Yep, true. Probably a better example would be
> > > > 
> > > > > > Array.new(2, {"foo"=\>"bar"})
> > > > 
> > > > =\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]
> > > 
> > > Though even then, it would appear (to someone wanting the specific  
> > > functionality of the OP, and probably 'most' cases) that the parameter  
> > > is used as a template, with .dup used for each instance.
> > 
> > Probably.
> > 
> > > I think the  
> > > example should illustrate that the objects are in fact the same, and  
> > > discuss the end result each has:
> > > 
> > > my\_array = Array.new( 2, { :foo =\> :bar } )  
> > > my\_array[1][:jimmy] = :jammy  
> > > p my\_array  
> > > #=\> [{:foo=\>:bar, :jimmy=\>:jammy}, {:foo=\>:bar, :jimmy=\>:jammy}]
> > > 
> > > my\_array = Array.new( 2 ){ { :foo =\> :bar } }  
> > > my\_array[1][:jimmy] = :jammy  
> > > p my\_array  
> > > #=\> [{:foo=\>:bar}, {:foo=\>:bar, :jimmy=\>:jammy}]
> > 
> > Nice, too. Or do
> > 
> > > > a = Array.new(2, {"foo"=\>"bar"})
> > 
> > =\> [{"foo"=\>"bar"}, {"foo"=\>"bar"}]
> > 
> > > > a.map{|o| o.object\_id}
> > 
> > =\> [135028744, 135028744]
> > 
> > > > a.map{|o| o.object\_id}.uniq
> > 
> > =\> [135028744]
> > 
> > Kind regards
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;robert
