[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Array::new

Jamie Hodkinson

4/25/2005 12:36:00 PM

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



7 Answers

Dave Baldwin

4/25/2005 12:46:00 PM

0


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
>



Jamie Hodkinson

4/25/2005 12:51:00 PM

0

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

4/25/2005 12:53:00 PM

0

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



Robert Klemme

4/25/2005 2:02:00 PM

0


"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

Gavin Kistner

4/25/2005 2:23:00 PM

0

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




Robert Klemme

4/25/2005 2:31:00 PM

0


"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


Dmitriy Genzel

4/25/2005 8:44:00 PM

0

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