Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Dumb "array of arrays" question

Reply
Thread Tools

Dumb "array of arrays" question

 
 
RichardOnRails
Guest
Posts: n/a
 
      08-25-2008
Hi,

I wrote the following intending to create an array of 3 element, each
being itself an array of two elements initialized to zero; Judging by
"inspect", I seem to have that:

a = Array.new(3, [0,0]) => [[0, 0], [0, 0], [0, 0]]

I tried the following, which confirms that a[0] is indeed a sub-
array.

a[0].inspect + "; " + a[0].class.to_s => [0, 0]; Array

Then I tried to assign a number (5) to the first element of the first
sub-array. What I got was more 5's than I bargained for:

a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]

What am I missing here?

Thanks in Advance,
Richard

 
Reply With Quote
 
 
 
 
Michael Guterl
Guest
Posts: n/a
 
      08-25-2008
On Mon, Aug 25, 2008 at 6:55 PM, RichardOnRails
<> wrote:
> Hi,
>
> I wrote the following intending to create an array of 3 element, each
> being itself an array of two elements initialized to zero; Judging by
> "inspect", I seem to have that:
>
> a = Array.new(3, [0,0]) => [[0, 0], [0, 0], [0, 0]]
>
> I tried the following, which confirms that a[0] is indeed a sub-
> array.
>
> a[0].inspect + "; " + a[0].class.to_s => [0, 0]; Array
>
> Then I tried to assign a number (5) to the first element of the first
> sub-array. What I got was more 5's than I bargained for:
>
> a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]
>
> What am I missing here?
>

Use the block form of Array.new

a = Array.new(3) { [0, 0] }
a[0][0] = 5

HTH,
Michael Guterl

 
Reply With Quote
 
 
 
 
Chris Shea
Guest
Posts: n/a
 
      08-25-2008
On Aug 25, 4:57*pm, RichardOnRails
<RichardDummyMailbox58...@uscomputergurus.com> wrote:
> Hi,
>
> I wrote the following intending to create an array of 3 element, each
> being itself an array of two elements initialized to zero; *Judging by
> "inspect", I seem to have that:
>
> a = Array.new(3, [0,0]) => [[0, 0], [0, 0], [0, 0]]
>
> I tried the following, *which confirms that a[0] is indeed a sub-
> array.
>
> a[0].inspect + "; " + a[0].class.to_s => [0, 0]; Array
>
> Then I tried to assign a number (5) to the first element of the first
> sub-array. What I got was more 5's than I bargained for:
>
> a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]
>
> What am I missing here?
>
> Thanks in Advance,
> Richard


This is a gotcha that trips up everyone the first time they come
across it. Array.new(size, obj) creates a new array with _size_ copies
of _obj_. That is, your array has three copies of the array [0,0].
Each one is the same as the other. So when you assign to the first
element of that array, all copies get updated. You'll want to use
Array.new with a block to get different objects:

a = Array.new(3, [0,0])
a # => [[0, 0], [0, 0], [0, 0]]
a.map {|element| element.object_id} # => [78860, 78860, 78860]

a2 = Array.new(3) {[0,0]}
a2 # => [[0, 0], [0, 0], [0, 0]]
a2.map {|element| element.object_id} # => [77710, 77700, 77690]

a2[0][0] = 5
a2 # => [[5, 0], [0, 0], [0, 0]]

HTH,
Chris
 
Reply With Quote
 
Todd Benson
Guest
Posts: n/a
 
      08-25-2008
On Mon, Aug 25, 2008 at 6:07 PM, Michael Guterl <> wrote:
> On Mon, Aug 25, 2008 at 6:55 PM, RichardOnRails
> <> wrote:
>> Hi,
>>
>> I wrote the following intending to create an array of 3 element, each
>> being itself an array of two elements initialized to zero; Judging by
>> "inspect", I seem to have that:
>>
>> a = Array.new(3, [0,0]) => [[0, 0], [0, 0], [0, 0]]
>>
>> I tried the following, which confirms that a[0] is indeed a sub-
>> array.
>>
>> a[0].inspect + "; " + a[0].class.to_s => [0, 0]; Array
>>
>> Then I tried to assign a number (5) to the first element of the first
>> sub-array. What I got was more 5's than I bargained for:
>>
>> a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]
>>
>> What am I missing here?
>>

> Use the block form of Array.new
>
> a = Array.new(3) { [0, 0] }
> a[0][0] = 5


There's also...

inner_dim = 2
inner_val = 0
outer_dim = 3
a = Array.new(outer_dim) { Array.new(inner_dim, inner_val) }

Why would someone do it this way? Because you can change what's
inside the new() instead of steadfastly saying it must be [0, 0].
Sort of moving data away from logic a little. Easier to debug, blah,
blah...

If that's not really a big deal, I would go Michael's and Chris's route.

Todd

 
Reply With Quote
 
RichardOnRails
Guest
Posts: n/a
 
      08-26-2008
On Aug 25, 6:57 pm, RichardOnRails
<RichardDummyMailbox58...@uscomputergurus.com> wrote:
> Hi,
>
> I wrote the following intending to create an array of 3 element, each
> being itself an array of two elements initialized to zero; Judging by
> "inspect", I seem to have that:
>
> a = Array.new(3, [0,0]) => [[0, 0], [0, 0], [0, 0]]
>
> I tried the following, which confirms that a[0] is indeed a sub-
> array.
>
> a[0].inspect + "; " + a[0].class.to_s => [0, 0]; Array
>
> Then I tried to assign a number (5) to the first element of the first
> sub-array. What I got was more 5's than I bargained for:
>
> a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]
>
> What am I missing here?
>
> Thanks in Advance,
> Richard


Hi y'all,

Many thanks.
Thanks to Michael for being first with a quick solution
Thanks to Todd for suggesting what might be more elegant in certain
circumstances.
Thanks to Chris for revealing exact how Ruby handles my construct and
the one I really want.

Best wishes,
Richard
 
Reply With Quote
 
Thomas B.
Guest
Posts: n/a
 
      08-26-2008
RichardOnRails wrote:
> a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]


You might want to have a look at the post
http://al2o3-cr.blogspot.com/2008/08/object-arr.html describing nicely
some details about pointers in Ruby. Might be a good addition to what
has already been said here.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
RichardOnRails
Guest
Posts: n/a
 
      08-28-2008
On Aug 26, 8:26 am, "Thomas B." <tpr...@gmail.com> wrote:
> RichardOnRails wrote:
> > a[0][0]=5 => [[5, 0], [5, 0], [5, 0]]

>
> You might want to have a look at the posthttp://al2o3-cr.blogspot.com/2008/08/object-arr.htmldescribing nicely
> some details about pointers in Ruby. Might be a good addition to what
> has already been said here.
> --
> Posted viahttp://www.ruby-forum.com/.


Hi Thomas,

Thanks for the link, which offers a lot of interesting things. On
aesthetic grounds, I'd like a white background. The black is tough
on a septuagenarian

But I have a more substantive question. The site says:

<quote>
[x] #=> [#<Object:0x2d8ce10>]
[x].dup #=> [#<Object:0x2d8ce10>]

As you see,

dup on an object makes a new object (the addresses differ) [referring
to earlier statements], but

dup on an array makes a new array but does not make a copy of the
elements - it just makes a new array with its elements pointing to the
original objects.
</quote>

My minor exception is that an array IS an object, so the two
paragraphs sound weird. He is contrasting an object of class Object
to an object of class Array.

More importantly, according to my tests below, dup'ing an array does
NOT make a new array. It returns the (address of/pointer to) the same
old array.

I am missing something?

Best wishes,
Richard

Code
====
x = Object.new
puts "1: " + x.inspect
puts "2: " + x.dup.inspect

a = [x]
ad = a.dup
puts "3: " + a.inspect+ "; " + a[0].inspect + "; " + a.class.to_s
puts "4: " + ad.inspect + "; " + ad[0].inspect + "; " + ad.class.to_s

Output
======
1: #<Object:0x2808138>
2: #<Object:0x28080c0>
3: [#<Object:0x2808138>]; #<Object:0x2808138>; Array
4: [#<Object:0x2808138>]; #<Object:0x2808138>; Array


 
Reply With Quote
 
Thomas B.
Guest
Posts: n/a
 
      08-28-2008
Hello Richard,

RichardOnRails wrote:
> My minor exception is that an array IS an object, so the two
> paragraphs sound weird. He is contrasting an object of class Object
> to an object of class Array.
>
> More importantly, according to my tests below, dup'ing an array does
> NOT make a new array. It returns the (address of/pointer to) the same
> old array.


dup'ing an array DOES make a new array, only the new array looks like
the old one, because Array#inspect doesn't return the address of the
array so you cannot see if it is exactly the same instance or not. But
there is a method to check it: equal?. It works like == in Java.

a=[whatever]
a.equal?(a) #=> true # the very same Array instance
a.equal?(a.dup) #=> false # it's another instance, only it looks like
the old one when inspect'ed

But still the whatever inside a and a.dup is exactly the same thing:
a[0].euqal?(a.dup[0]) #=> true

That proves the copy is shallow - there's a new object, but it holds old
references.

> 3: [#<Object:0x2808138>]; #<Object:0x2808138>; Array
> 4: [#<Object:0x2808138>]; #<Object:0x2808138>; Array


The [#<Object:0x2808138>]'s here are in fact different objects, only
they look the same.

Hope that helps a bit.

T.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Adam Shelly
Guest
Posts: n/a
 
      08-28-2008
On 8/28/08, Thomas B. <> wrote:
> Hello Richard,
>
> RichardOnRails wrote:
> > More importantly, according to my tests below, dup'ing an array does
> > NOT make a new array. It returns the (address of/pointer to) the same
> > old array.

>
> dup'ing an array DOES make a new array, only the new array looks like
> the old one, because Array#inspect doesn't return the address of the
> array so you cannot see if it is exactly the same instance or not.


> > 3: [#<Object:0x2808138>]; #<Object:0x2808138>; Array
> > 4: [#<Object:0x2808138>]; #<Object:0x2808138>; Array

>
> The [#<Object:0x2808138>]'s here are in fact different objects, only
> they look the same.
>

You can prove they are different objects this way:
code:
a = [Object.new]; ad = a.dup
puts a.inspect+ ", #{a.object_id}"
puts ad.inspect+ ", #{ad.object_id}"
output:
[#<Object:0x2842310>], 21107090
[#<Object:0x2842310>], 21107070

-Adam

 
Reply With Quote
 
RichardOnRails
Guest
Posts: n/a
 
      08-28-2008
On Aug 28, 1:07 pm, Adam Shelly <adam.she...@gmail.com> wrote:
> On 8/28/08, Thomas B. <tpr...@gmail.com> wrote:
>
>
>
> > Hello Richard,

>
> > RichardOnRails wrote:
> > > More importantly, according to my tests below, dup'ing an array does
> > > NOT make a new array. It returns the (address of/pointer to) the same
> > > old array.

>
> > dup'ing an array DOES make a new array, only the new array looks like
> > the old one, because Array#inspect doesn't return the address of the
> > array so you cannot see if it is exactly the same instance or not.
> > > 3: [#<Object:0x2808138>]; #<Object:0x2808138>; Array
> > > 4: [#<Object:0x2808138>]; #<Object:0x2808138>; Array

>
> > The [#<Object:0x2808138>]'s here are in fact different objects, only
> > they look the same.

>
> You can prove they are different objects this way:
> code:
> a = [Object.new]; ad = a.dup
> puts a.inspect+ ", #{a.object_id}"
> puts ad.inspect+ ", #{ad.object_id}"
> output:
> [#<Object:0x2842310>], 21107090
> [#<Object:0x2842310>], 21107070
>
> -Adam


Hi Adam,

Thanks for example. My mistake was thinking that a.inspect, which
yielded [#<Object:0x2842310>] was yielding the a's object_id.

I speculated that inspect yielded its receiver's content's object_id.
That's wrong, as evidenced by the following code. So is inspect
returning in this instance?

Best wishes,
Richard

a = [x]
ad = a.dup

puts "1: " + a.object_id.to_s+ "; " + a[0].object_id.to_s + "; " +
a.inspect
puts "2: " + ad.object_id.to_s + "; " + ad[0].object_id.to_s + "; " +
ad.inspect

1: 20987380; 20987470; [#<Object:0x2807c9c>]
2: 20987370; 20987470; [#<Object:0x2807c9c>]
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dumb, Dumb Vista Au79 Computer Support 4 02-11-2007 03:40 PM
Probably a dumb s/// question. Mark Healey Perl 2 03-16-2005 04:51 PM
Dumb, dumb dumb Qestion David Napierkowski Digital Photography 6 10-31-2004 11:14 PM
dumb newbie question (or newbie dumb question) Jerry C. Perl Misc 8 11-23-2003 04:11 AM
Re: Dumb question Walter Roberson Cisco 1 07-23-2003 01:05 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57