# Why do arrays work this way?

**URL:** <https://rubytalk.org/t/why-do-arrays-work-this-way/19049>\
**Category:** ruby-talk\
**Created:** [17 June 2005 23:51 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049 "2005-06-17T23:51:05Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nigel\_Wilkinson1](https://avatars.discourse-cdn.com/v4/letter/n/ecae2f/32.png) [@Nigel\_Wilkinson1](https://rubytalk.org/u/Nigel_Wilkinson1)\
**Post date:** [17 June 2005 23:51 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/1 "2005-06-17T23:51:05Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [17 June 2005 23:57 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/2 "2005-06-17T23:57:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [17 June 2005 23:58 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/3 "2005-06-17T23:58:34Z")

</div>

> 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

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

---

<div class="post-metadata">

**Author:** ![Kent\_Sibilev1](https://avatars.discourse-cdn.com/v4/letter/k/9d8465/32.png) [@Kent\_Sibilev1](https://rubytalk.org/u/Kent_Sibilev1)\
**Post date:** [18 June 2005 00:04 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/4 "2005-06-18T00:04:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Devin\_Mullins](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Devin\_Mullins](https://rubytalk.org/u/Devin_Mullins)\
**Post date:** [18 June 2005 00:08 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/5 "2005-06-18T00:08:29Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Erik\_Veenstra3](https://avatars.discourse-cdn.com/v4/letter/e/f9ae1b/32.png) [@Erik\_Veenstra3](https://rubytalk.org/u/Erik_Veenstra3)\
**Post date:** [18 June 2005 00:15 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/6 "2005-06-18T00:15:33Z")

</div>

> 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.erikveen.dds.nl/](http://www.erikveen.dds.nl/)

[1] [http://www.rubycentral.com/book/index.html](http://www.rubycentral.com/book/index.html)

---

<div class="post-metadata">

**Author:** ![Florian\_Gross2](https://avatars.discourse-cdn.com/v4/letter/f/b4bc9f/32.png) [@Florian\_Gross2](https://rubytalk.org/u/Florian_Gross2)\
**Post date:** [18 June 2005 00:56 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/7 "2005-06-18T00:56:00Z")

</div>

Nigel Wilkinson wrote:

> irb(main):058:0\> a=[1,2,3,4,5]; b = a; b[3] = 'w'; a  
> =\> [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.

In Ruby variables are just names for objects. If you do  
&nbsp;&nbsp;&nbsp;my\_array = [1, 2, 3]  
you name an array with the elements 1, 2 and 3 as my\_array.

If you then do  
&nbsp;&nbsp;&nbsp;my\_numbers = my\_array  
you just give the object named my\_array another name (my\_numbers). So what you did was just variable aliasing and nothing else.

Please note that in Ruby  
&nbsp;&nbsp;&nbsp;var += 5  
is exactly the same as  
&nbsp;&nbsp;&nbsp;var = var + 5  
which binds another name to the variable. This means that  
&nbsp;&nbsp;&nbsp;a = 5  
&nbsp;&nbsp;&nbsp;b = a  
&nbsp;&nbsp;&nbsp;b += 1  
&nbsp;&nbsp;&nbsp;[a, b] # =\> [5, 6]  
because the objects didn't change at all -- you just decided to rename things.

Other languages with value semantics typically create a copy of the original object when you assign them to anything. This is typically done in Ruby like  
&nbsp;&nbsp;&nbsp;my\_array = [1, 2, 3]  
&nbsp;&nbsp;&nbsp;my\_copy = my\_array.clone  
which will then give you the behavior you intended:  
&nbsp;&nbsp;&nbsp;my\_array[0] = :changed  
&nbsp;&nbsp;&nbsp;my\_array # =\> [:changed, 2, 3]  
&nbsp;&nbsp;&nbsp;my\_copy # =\> [1, 2, 3]

I think that Ruby's behavior is correct because languages where you explicitly have to specify that you want a reference to an object instead of a copy of it (like PHP used to do it even for values that are typically automatically passed by reference in the traditional languages like C++ and Java) cause more confusion. In Ruby you just give names to objects and ask them for a copy when you want one. It takes a short introduction (simply because languages that use pass-by-value somewhere are more common), but leads to less trouble later.

---

<div class="post-metadata">

**Author:** ![Erik\_Veenstra3](https://avatars.discourse-cdn.com/v4/letter/e/f9ae1b/32.png) [@Erik\_Veenstra3](https://rubytalk.org/u/Erik_Veenstra3)\
**Post date:** [18 June 2005 00:20 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/8 "2005-06-18T00:20:33Z")

</div>

> 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.erikveen.dds.nl/](http://www.erikveen.dds.nl/)

---

<div class="post-metadata">

**Author:** ![Tim\_Sutherland1](https://avatars.discourse-cdn.com/v4/letter/t/8e7dd6/32.png) [@Tim\_Sutherland1](https://rubytalk.org/u/Tim_Sutherland1)\
**Post date:** [18 June 2005 01:25 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/9 "2005-06-18T01:25:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Nigel\_Wilkinson1](https://avatars.discourse-cdn.com/v4/letter/n/ecae2f/32.png) [@Nigel\_Wilkinson1](https://rubytalk.org/u/Nigel_Wilkinson1)\
**Post date:** [18 June 2005 09:07 UTC](https://rubytalk.org/t/why-do-arrays-work-this-way/19049/10 "2005-06-18T09:07:30Z")

</div>

Thanks everyone

Nigel

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