[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Why do arrays work this way?

Nigel Wilkinson

6/17/2005 11:51:00 PM

Hi folks

I'm using ruby 1.8.2 as comes with Mandriva 2005LE and get the following
behaviour with arrays which doesn't seem logical to me.

In irb I do

irb(main):058:0* a=[1,2,3,4,5]
=> [1, 2, 3, 4, 5]

straight forward enough

irb(main):059:0> b=a
=> [1, 2, 3, 4, 5]
irb(main):060:0> c=a
=> [1, 2, 3, 4, 5]

I've set 2 more variables to equal 'a'

irb(main):061:0> b[3] = 'w'
=> "w"

I believe this changes index 3 in'b' to now be equal to 'w'

do
irb(main):062:0> b
=> [1, 2, 3, "w", 5]

that's exactly as I expected, BUT

irb(main):063:0> a
=> [1, 2, 3, "w", 5]
irb(main):064:0> c
=> [1, 2, 3, "w", 5]

so what's the logic behind 'a' & 'c' changing when I change 'b'.

Is this a bug? and if not what's the reasoning behind this behaviour please.



Best Rgds from confused of Heathfield
Nigel
__________________________________________________________________________
Disclaimer
Any opinions expressed in this email are not necessarily those of my wife


9 Answers

Joel VanderWerf

6/17/2005 11:57:00 PM

0

Nigel Wilkinson wrote:
> Hi folks
>
> I'm using ruby 1.8.2 as comes with Mandriva 2005LE and get the following
> behaviour with arrays which doesn't seem logical to me.
>
> In irb I do
>
> irb(main):058:0* a=[1,2,3,4,5]
> => [1, 2, 3, 4, 5]
>
> straight forward enough
>
> irb(main):059:0> b=a
> => [1, 2, 3, 4, 5]
> irb(main):060:0> c=a
> => [1, 2, 3, 4, 5]
>
> I've set 2 more variables to equal 'a'
>
> irb(main):061:0> b[3] = 'w'
> => "w"
>
> I believe this changes index 3 in'b' to now be equal to 'w'
>
> do
> irb(main):062:0> b
> => [1, 2, 3, "w", 5]
>
> that's exactly as I expected, BUT
>
> irb(main):063:0> a
> => [1, 2, 3, "w", 5]
> irb(main):064:0> c
> => [1, 2, 3, "w", 5]
>
> so what's the logic behind 'a' & 'c' changing when I change 'b'.

It's the same array in each case. The 3 variables each refer to it.


James Gray

6/17/2005 11:59:00 PM

0

On Jun 17, 2005, at 6:51 PM, Nigel Wilkinson wrote:

> Hi folks
>
> I'm using ruby 1.8.2 as comes with Mandriva 2005LE and get the
> following behaviour with arrays which doesn't seem logical to me.

[snip examples]

> so what's the logic behind 'a' & 'c' changing when I change 'b'.
>
> Is this a bug? and if not what's the reasoning behind this
> behaviour please.

In Ruby, everything is an object, but variables are just references
to those objects. Your `b=a` sets b to reference the same object as
a. Thus, when you make a change to one, they all change. Now, if
you used `b=a.dup` b would be set to reference a copy of a, and the
changes would not filter over.

Try playing around in irb as you have been doing, but calling
object_id() on the arrays to seem which objects are the same.

Hope that helps.

James Edward Gray II


Kent Sibilev

6/18/2005 12:04:00 AM

0

When you make an assignment b = a, you assign the variable 'b' a
reference to the same array variable 'a' refers to. If you want to
have a copy of array a use dup method like

b = a.dup

Kent.


On 6/17/05, Nigel Wilkinson <nigel@waspz.co.uk> wrote:
> Hi folks
>
> I'm using ruby 1.8.2 as comes with Mandriva 2005LE and get the following
> behaviour with arrays which doesn't seem logical to me.
>
> In irb I do
>
> irb(main):058:0* a=[1,2,3,4,5]
> => [1, 2, 3, 4, 5]
>
> straight forward enough
>
> irb(main):059:0> b=a
> => [1, 2, 3, 4, 5]
> irb(main):060:0> c=a
> => [1, 2, 3, 4, 5]
>
> I've set 2 more variables to equal 'a'
>
> irb(main):061:0> b[3] = 'w'
> => "w"
>
> I believe this changes index 3 in'b' to now be equal to 'w'
>
> do
> irb(main):062:0> b
> => [1, 2, 3, "w", 5]
>
> that's exactly as I expected, BUT
>
> irb(main):063:0> a
> => [1, 2, 3, "w", 5]
> irb(main):064:0> c
> => [1, 2, 3, "w", 5]
>
> so what's the logic behind 'a' & 'c' changing when I change 'b'.
>
> Is this a bug? and if not what's the reasoning behind this behaviour please.
>
>
>
> Best Rgds from confused of Heathfield
> Nigel
> __________________________________________________________________________
> Disclaimer
> Any opinions expressed in this email are not necessarily those of my wife
>
>


Devin Mullins

6/18/2005 12:08:00 AM

0

As in many modern languages (Java, most popularly, but I'd imagine
Python, too), everything's a pointer, so to speak. If you want a copy,
you should say b=a.dup, instead. Note, however, that not even that's
perfect.

While this works:

irb(main):001:0> a=[1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> b=a.dup
=> [1, 2, 3, 4, 5]
irb(main):003:0> b[2]=7
=> 7
irb(main):004:0> a
=> [1, 2, 3, 4, 5]
irb(main):005:0> b
=> [1, 2, 7, 4, 5]
irb(main):006:0>

There is still a pitfall if the Objects that your Array contains are
mutable (changeable):

irb(main):006:0> a=["hello","dog","cat"]
=> ["hello", "dog", "cat"]
irb(main):007:0> b=a.dup
=> ["hello", "dog", "cat"]
irb(main):008:0> b[2]="feline"
=> "feline"
irb(main):009:0> b[1].reverse!
=> "god"
irb(main):010:0> a
=> ["hello", "god", "cat"]
irb(main):011:0> b
=> ["hello", "god", "feline"]
irb(main):012:0>

Note that b[2]=... makes the new separate b Array point to a brand new
String object, while b[1].reverse! modifies the existing String object
-- the one that both a and b both point to. This is because Array#dup
(and in general Object#dup) is a shallow copy. In other words,
Object#dup is not "recursive" on the Objects inside.

Hope that helps, and hope it doesn't kill your buzz. :)

Devin



Erik Veenstra

6/18/2005 12:14:00 AM

0

> a=[1,2,3,4,5]

This creates a specific object of class Array. "a" is a pointer
to the array-object. Just to be sure, I didn't say: "a" is the
array-object...

> b=a
>
> c=a

Now "b" and "c" point to the same object as "a".

> so what's the logic behind 'a' & 'c' changing when I change
> 'b'.

I think you can now answer it yourself...

> Is this a bug? and if not what's the reasoning behind this
> behaviour please.

There's only one type for variables in Ruby: pointer. Pointer
to nothing (=nil) or pointer to an object. There's no such
thing as storing an object in a variable.

Have you read "Programming Ruby, The Pragmatic Programmer's
Guide" [1]?

Extra info: In Java, there's a difference between "int" and
"Integer". Variables of type "int" store direct values, whereas
variables of type "Integer" only store pointers, like in Ruby.
Pointers in Ruby are typeless and pointers in Java are of a
certain type.

gegroet,
Erik V. - http://www.erikve...

[1] http://www.rubycentral.com/book/...

Erik Veenstra

6/18/2005 12:17:00 AM

0

> As in many modern languages (Java, most popularly, but I'd
> imagine Python, too), everything's a pointer, so to speak.

Not everything in Java is a pointer. Compare "int" with
"Integer": a huge difference.

Sorry, I didn't realize that this is the Ruby news groups...

gegroet,
Erik V. - http://www.erikve...

Florian Groß

6/18/2005 12:56:00 AM

0

timsuth

6/18/2005 1:21:00 AM

0

In article <pan.2005.06.18.00.13.48.594023@erikveen.dds.nl>, Erik Veenstra
wrote:
[...]
>There's only one type for variables in Ruby: pointer. Pointer
>to nothing (=nil) or pointer to an object.
[...]

nil is just an object.

Nigel Wilkinson

6/18/2005 9:08:00 AM

0

--On Saturday, June 18, 2005 09:04:28 +0900 Kent Sibilev <ksruby@gmail.com>
wrote:

> When you make an assignment b = a, you assign the variable 'b' a
> reference to the same array variable 'a' refers to. If you want to
> have a copy of array a use dup method like
>
> b = a.dup
>
> Kent.
>
Thanks everyone

Nigel