Array::new

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

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

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
            Array.new(2, Hash.new) » [{}, {}]
is given, I agree that this documentation is misleading for beginners.

Regards,
Adriano.

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
>

"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
            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

    robert

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
            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"}]

"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

    robert

···

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

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
            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

    robert