# Does each work on a copy?

**URL:** <https://rubytalk.org/t/does-each-work-on-a-copy/6347>\
**Category:** ruby-talk\
**Created:** [12 June 2003 13:46 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347 "2003-06-12T13:46:45Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rasputin3](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Rasputin3](https://rubytalk.org/u/Rasputin3)\
**Post date:** [12 June 2003 13:46 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/1 "2003-06-12T13:46:45Z")

</div>

This has me confused (It’s getting to be a frequent experience).

----------------8\<----------------

SPACE = 1

a = Array.new(5)  
b = Array.new(5, SPACE)

a.each { |el|  
el = SPACE  
}

puts “a = #{a.join(”-")}“  
puts “b = #{b.join(”-”)}"

----------------8\<----------------

I’d expect to have a first output line similar to the second,but I get:

rasputin@shrike rasputin$ ruby /tmp/q  
a = ----  
b = 1-1-1-1-1  
rasputin@shrike rasputin$

Now, is this because each is returning a copy of the element?  
It’s the most plausible explanation  
(because if I replace a.each with a.collect! it works as I expected)  
but if so I’m surprised it hasn’t bitten me on the ass before.

I know the Array is full of nils, but can’t see why that would  
cause what I’n seeing.

Please hit me wirh a clue bat. Thanks.

> **···**
>
> –  
> Rasputin :: Jack of All Trades - Master of Nuns

---

<div class="post-metadata">

**Author:** ![Mauricio\_Fernndez](https://avatars.discourse-cdn.com/v4/letter/m/e495f1/32.png) [@Mauricio\_Fernndez](https://rubytalk.org/u/Mauricio_Fernndez)\
**Post date:** [12 June 2003 14:01 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/2 "2003-06-12T14:01:46Z")

</div>

> SPACE = 1
> 
> a = Array.new(5)  
> b = Array.new(5, SPACE)
> 
> a.each { |el|  
> el = SPACE  
> }

You are _not_ modifying the elements inside a.  
a.each { |el|  
works like the following:  
a.each { el = corresponding\_element\_from\_a

If you assign to el you’ll only change the reference (ie. what the local  
is pointing to), not the underlying object.

However the following would work  
a.each\_with\_index { |el,i| a[i] = SPACE }  
(it is ugly and inefficient, though)

> puts “a = #{a.join(”-“)}”  
> puts “b = #{b.join(”-“)}”
> 
> ----------------8\<----------------
> 
> I’d expect to have a first output line similar to the second,but I get:
> 
> rasputin@shrike rasputin$ ruby /tmp/q  
> a = ----  
> b = 1-1-1-1-1  
> rasputin@shrike rasputin$
> 
> Now, is this because each is returning a copy of the element?  
> It is giving you a _reference_ to the element.  
> Consider:

> > a = %w{BLA FOO BAZ}  
> > =\> [“BLA”, “FOO”, “BAZ”]  
> > a.each{ |x| x.downcase! }  
> > =\> [“bla”, “foo”, “baz”]  
> > a  
> > =\> [“bla”, “foo”, “baz”]

> It’s the most plausible explanation  
> (because if I replace a.each with a.collect! it works as I expected)  
> but if so I’m surprised it hasn’t bitten me on the ass before.

collect! works because the value of ‘el = SPACE’ is SPACE, and collect  
takes the value of the block in each iteration.

> **···**
>
> On Thu, Jun 12, 2003 at 10:46:45PM +0900, Rasputin wrote:
> 
> –  
> \_ \_
> 
> > > \_\_ \_\_ _| |_ \_\_\_ \_ \_\_ \_\_\_ \_\_ \_ \_ \_\_  
> > > '\_ \ / _`| __/__ | '_` \_ \ / ` | ’ \   
> > > ) | (| | |_\_\_ \ | | | | | (_| | | | |  
> > > .\_\_/ \_,_|\ __|__ /| |_| |_|\__,_|_| |\_|  
> > > Running Debian GNU/Linux Sid (unstable)  
> > > batsman dot geo at yahoo dot com
> 
> You will not censor me through bug terrorism.  
> – James Troup

---

<div class="post-metadata">

**Author:** ![Andrew\_Walrond1](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@Andrew\_Walrond1](https://rubytalk.org/u/Andrew_Walrond1)\
**Post date:** [12 June 2003 14:02 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/3 "2003-06-12T14:02:17Z")

</div>

Rasputin wrote:

> This has me confused (It’s getting to be a frequent experience).
> 
> ----------------8\<----------------
> 
> SPACE = 1
> 
> a = Array.new(5)  
> b = Array.new(5, SPACE)
> 
> a.each { |el|  
> el = SPACE  
> }

el is simply a reference to the array element. by el = SPACE simply  
makes el refer to SPACE instead; it has no effect on the array element

remember that pretty much everything is a reference and you won’t go far  
wrong

Andrew Walrond

---

<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:** [12 June 2003 14:05 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/4 "2003-06-12T14:05:05Z")

</div>

Rasputin wrote:

> This has me confused (It’s getting to be a frequent experience).
> 
> ----------------8\<----------------
> 
> SPACE = 1
> 
> a = Array.new(5)  
> b = Array.new(5, SPACE)
> 
> a.each { |el|  
> el = SPACE

‘el’ is a local variable which is bound to successive elements of the  
array. When you assign to el, you change the binding of the local  
variable, without touching the array or the element itself.

What you may want here is map!:

a.map! { |el| SPACE }

This replaces each element of the array with SPACE.

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [12 June 2003 14:22 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/5 "2003-06-12T14:22:26Z")

</div>

“Rasputin” [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) schrieb im Newsbeitrag  
[news:20030612134643.GA76491@shrike.private.submonkey.net](mailto:news:20030612134643.GA76491@shrike.private.submonkey.net)…

> This has me confused (It’s getting to be a frequent experience).
> 
> ----------------8\<----------------
> 
> SPACE = 1
> 
> a = Array.new(5)  
> b = Array.new(5, SPACE)
> 
> a.each { |el|  
> el = SPACE  
> }
> 
> puts “a = #{a.join(”-“)}”  
> puts “b = #{b.join(”-“)}”
> 
> ----------------8\<----------------
> 
> I’d expect to have a first output line similar to the second,but I get:
> 
> rasputin@shrike rasputin$ ruby /tmp/q  
> a = ----  
> b = 1-1-1-1-1  
> rasputin@shrike rasputin$
> 
> Now, is this because each is returning a copy of the element?  
> It’s the most plausible explanation  
> (because if I replace a.each with a.collect! it works as I expected)  
> but if so I’m surprised it hasn’t bitten me on the ass before.
> 
> I know the Array is full of nils, but can’t see why that would  
> cause what I’n seeing.
> 
> Please hit me wirh a clue bat. Thanks.

Clue bat: your block assigns to a local variable “e”, which does not  
change the array. You can assign as much as you like to “e”, it does not  
have any effect on “a”.

If you want to modify the array use a.map! or a.collect! instead of  
a.each:

irb(main):001:0\> SPACE = 1  
1  
irb(main):002:0\>  
irb(main):003:0\* a = Array.new(5)  
[nil, nil, nil, nil, nil]  
irb(main):004:0\> b = Array.new(5, SPACE)  
[1, 1, 1, 1, 1]  
irb(main):005:0\>  
irb(main):006:0\* a.map! { SPACE }  
[1, 1, 1, 1, 1]  
irb(main):007:0\>  
irb(main):008:0\*  
irb(main):009:0\* puts “a = #{a.join(”-“)}”  
a = 1-1-1-1-1  
nil  
irb(main):010:0\> puts “b = #{b.join(”-“)}”  
b = 1-1-1-1-1  
nil  
irb(main):011:0\>

Cheers

```
robert

```

---

<div class="post-metadata">

**Author:** ![Rasputin3](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Rasputin3](https://rubytalk.org/u/Rasputin3)\
**Post date:** [12 June 2003 14:14 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/6 "2003-06-12T14:14:37Z")

</div>

- Andrew Walrond [andrew@walrond.org](mailto:andrew@walrond.org) [030612 15:02]:

> Rasputin wrote:
> 
> > This has me confused (It’s getting to be a frequent experience).
> > 
> > ----------------8\<----------------
> > 
> > SPACE = 1
> > 
> > a = Array.new(5)  
> > b = Array.new(5, SPACE)
> > 
> > a.each { |el|  
> > el = SPACE  
> > }
> 
> el is simply a reference to the array element. by el = SPACE simply  
> makes el refer to SPACE instead; it has no effect on the array element
> 
> remember that pretty much everything is a reference and you won’t go far  
> wrong

I thought so, until this happened!  
The array was full of references, so I thought el held the  
reference from the Array.

It seems to hold a copy of the reference…

hmm, fiddly. I’ll go for the collect! (aka map!) fix that I mentioned  
(and Joel suggested too, thanks).

(This is from a noughts and crosses / tic-tac-toe board class I’m  
writing using ruby-libneural, so I need to clear the board after every  
game, otherwise I’d use the second Array constructor instead).

Thanks to all repleyers (is that a word?) 🙂

> **···**
>
> –  
> Rasputin :: Jack of All Trades - Master of Nuns

---

<div class="post-metadata">

**Author:** ![Jason\_Creighton1](https://avatars.discourse-cdn.com/v4/letter/j/ecc23a/32.png) [@Jason\_Creighton1](https://rubytalk.org/u/Jason_Creighton1)\
**Post date:** [12 June 2003 18:43 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/7 "2003-06-12T18:43:44Z")

</div>

No, it doesn’t. When you do a:

a = “Hello world, nice to meet you!”.split(’ ')  
a.each { |word| word = “lala” }  
p a  
[“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]

You’re binding word to a different object, not changing the objects themselves. If you did this:

a = “Hello world, nice to meet you!”.split(’ ')  
a.each { |word| word.upcase! }  
p a  
[“HELLO”, “WORLD,”, “NICE”, “TO”, “MEET”, “YOU!”]

It’s the same thing that happens when you do this:

string1 = “Hello, world!”  
string2 = string1  
string2 = “Hi!”  
p string1  
“Hello, world!”

You haven’t changed the object that string1 points to: You’ve made a new string object (“Hi!”) and bind string2 to that. If you did a:

string1 = “Hello, world!”  
string2 = string1  
string2[0] = “J”  
p string1  
“Jello, world!”

Here you call the = method of the object that string2 points to,(no rebinding of string2) which means that string1 and string2 still point to the same object.

Jason Creighton

> **···**
>
> On Thu, 12 Jun 2003 23:14:37 +0900 Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:
> 
> > > remember that pretty much everything is a reference and you won’t go far  
> > > wrong
> > 
> > I thought so, until this happened!  
> > The array was full of references, so I thought el held the  
> > reference from the Array.
> > 
> > It seems to hold a copy of the reference…

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich2](https://avatars.discourse-cdn.com/v4/letter/j/ecc23a/32.png) [@Jim\_Weirich2](https://rubytalk.org/u/Jim_Weirich2)\
**Post date:** [13 June 2003 00:05 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/8 "2003-06-13T00:05:44Z")

</div>

I’ve always felt that thinking about Ruby variables and objects in terms  
of references was a bad idea. I prefer to think about it in terms of  
objects and names. You have objects, and you have names that can be  
bound to objects. In your case, the name el is bound to a particular  
object. You can modify the binding (by assigning to el), and you can  
modify the object (by sending it messages that cause it to change  
state). But to change what the array holds, you must send messages to  
the array object itself.

No need to think about references at all.

I wrote a bit about this topic before, so I won’t go into it here. You  
can read my initial posting at  
[http://www.rubygarden.org/ruby?VariablesAndObjects](http://www.rubygarden.org/ruby?VariablesAndObjects).

Thanks.

> **···**
>
> On Thu, 2003-06-12 at 10:14, Rasputin wrote:
> 
> > - Andrew Walrond [andrew@walrond.org](mailto:andrew@walrond.org) [030612 15:02]:
> > 
> > > remember that pretty much everything is a reference and you won’t go far  
> > > wrong
> > 
> > I thought so, until this happened!  
> > The array was full of references, so I thought el held the  
> > reference from the Array.
> 
> ## – – Jim Weirich [jweirich@one.net](mailto:jweirich@one.net)[http://onestepback.org](http://onestepback.org)
> 
> “Beware of bugs in the above code; I have only proved it correct,  
> not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

---

<div class="post-metadata">

**Author:** ![Mauricio\_Fernndez](https://avatars.discourse-cdn.com/v4/letter/m/e495f1/32.png) [@Mauricio\_Fernndez](https://rubytalk.org/u/Mauricio_Fernndez)\
**Post date:** [13 June 2003 05:32 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/9 "2003-06-13T05:32:35Z")

</div>

AFAIK that’s the terminology used in Smalltalk.  
Is it just me, or are we collectively gravitating towards Smalltalk? 😉

> **···**
>
> On Fri, Jun 13, 2003 at 09:05:44AM +0900, Jim Weirich wrote:
> 
> > > I thought so, until this happened!  
> > > The array was full of references, so I thought el held the  
> > > reference from the Array.
> > 
> > I’ve always felt that thinking about Ruby variables and objects in terms  
> > of references was a bad idea. I prefer to think about it in terms of  
> > objects and names. You have objects, and you have names that can be  
> > bound to objects.
> 
> –  
> \_ \_
> 
> > > \_\_ \_\_ _| |_ \_\_\_ \_ \_\_ \_\_\_ \_\_ \_ \_ \_\_  
> > > '\_ \ / _`| __/__ | '_` \_ \ / ` | ’ \   
> > > ) | (| | |_\_\_ \ | | | | | (_| | | | |  
> > > .\_\_/ \_,_|\ __|__ /| |_| |_|\__,_|_| |\_|  
> > > Running Debian GNU/Linux Sid (unstable)  
> > > batsman dot geo at yahoo dot com
> 
> My apologies if I sound angry. I feel like I’m talking to a void.  
> – Avery Pennarun

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [13 June 2003 10:31 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/10 "2003-06-13T10:31:35Z")

</div>

“Jason Creighton” [androflux@remove.to.reply.softhome.net](mailto:androflux@remove.to.reply.softhome.net) schrieb im  
Newsbeitrag  
[news:20030612123014.33a6449b.androflux@remove.to.reply.softhome.net](mailto:news:20030612123014.33a6449b.androflux@remove.to.reply.softhome.net)…

> > > remember that pretty much everything is a reference and you won’t go  
> > > far  
> > > wrong
> > 
> > I thought so, until this happened!  
> > The array was full of references, so I thought el held the  
> > reference from the Array.
> > 
> > It seems to hold a copy of the reference…
> 
> No, it doesn’t. When you do a:

Sorry, but in fact you’re wrong. The reference is copied indeed.

> a = “Hello world, nice to meet you!”.split(’ ')  
> a.each { |word| word = “lala” }  
> p a  
> [“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]
> 
> You’re binding word to a different object, not changing the objects  
> themselves.

Binding “word” to another object is indeed done by copying the reference  
to the other object. Or in other terms, after this assignment there is  
one more reference to the object.

a=“foo” # one ref to “foo”  
b=b # two refs to “foo”  
a=nil # one ref to “foo”  
b=nil # zero refs to “foo”

I think you did want to say the right thing but mixed up terms a little.

Maybe Perl has contributed to the confusion since it in fact does some  
aliasing of references in arrays on function invocations the allow a  
function to change array element references directly by simply assigning.  
IMHO the ruby way is much cleaner and easier to understand.

Kind regards

```
robert

```

> **···**
>
> > On Thu, 12 Jun 2003 23:14:37 +0900 \> Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:

---

<div class="post-metadata">

**Author:** ![Rasputin3](https://avatars.discourse-cdn.com/v4/letter/r/9d8465/32.png) [@Rasputin3](https://rubytalk.org/u/Rasputin3)\
**Post date:** [13 June 2003 23:01 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/11 "2003-06-13T23:01:40Z")

</div>

- Jason Creighton [androflux@remove.to.reply.softhome.net](mailto:androflux@remove.to.reply.softhome.net) [030612 19:44]:

> > > remember that pretty much everything is a reference and you won’t go far  
> > > wrong
> > 
> > I thought so, until this happened!  
> > The array was full of references, so I thought el held the  
> > reference from the Array.
> > 
> > It seems to hold a copy of the reference…
> 
> No, it doesn’t. When you do a:
> 
> a = “Hello world, nice to meet you!”.split(’ ')  
> a.each { |word| word = “lala” }  
> p a  
> [“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]
> 
> You’re binding word to a different object, not changing the objects themselves. If you did this:

By ‘copy of the reference’ I meant:

ary = %w( a b c d e)  
ary.each { |r| r = “X” }

r is given a copy of the ‘reference’ (apology for the Perlism),  
so when you point (ugh, and the Cism) r at “X” you’re updating a  
copy of the reference, not the original reference. Is that about right?

And in the below code,

string2 = “Hi”  
is just pointing string2 to a new object, whereas  
string2[0] = “J”  
is editing the object through the string2 reference, just  
as word.upcase! below is doing, as opposed to the |el| el = SPACE  
in my original post.

Sorry for the list noise, think I’ve got it now.  
Thanks again for all replies.

> **···**
>
> > On Thu, 12 Jun 2003 23:14:37 +0900 \> Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:
> 
> > a = “Hello world, nice to meet you!”.split(’ ')  
> > a.each { |word| word.upcase! }  
> > p a  
> > [“HELLO”, “WORLD,”, “NICE”, “TO”, “MEET”, “YOU!”]
> > 
> > It’s the same thing that happens when you do this:
> > 
> > string1 = “Hello, world!”  
> > string2 = string1  
> > string2 = “Hi!”  
> > p string1  
> > “Hello, world!”
> > 
> > You haven’t changed the object that string1 points to: You’ve made a new string object (“Hi!”) and bind string2 to that. If you did a:
> > 
> > string1 = “Hello, world!”  
> > string2 = string1  
> > string2[0] = “J”  
> > p string1  
> > “Jello, world!”
> > 
> > Here you call the = method of the object that string2 points to,(no rebinding of string2) which means that string1 and string2 still point to the same object.
> > 
> > Jason Creighton
> 
> –  
> Rasputin :: Jack of All Trades - Master of Nuns

---

<div class="post-metadata">

**Author:** ![Jim\_Weirich2](https://avatars.discourse-cdn.com/v4/letter/j/ecc23a/32.png) [@Jim\_Weirich2](https://rubytalk.org/u/Jim_Weirich2)\
**Post date:** [13 June 2003 11:01 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/12 "2003-06-13T11:01:12Z")

</div>

I first learned that way of thinking in Lisp.

> **···**
>
> On Fri, 2003-06-13 at 01:32, Mauricio Fernández wrote:
> 
> > AFAIK that’s the terminology used in Smalltalk.  
> > Is it just me, or are we collectively gravitating towards Smalltalk? 😉
> 
> ## – – Jim Weirich [jweirich@one.net](mailto:jweirich@one.net)[http://onestepback.org](http://onestepback.org)
> 
> “Beware of bugs in the above code; I have only proved it correct,  
> not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

---

<div class="post-metadata">

**Author:** ![HAL\_9000](https://avatars.discourse-cdn.com/v4/letter/h/90ced4/32.png) [@HAL\_9000](https://rubytalk.org/u/HAL_9000)\
**Post date:** [13 June 2003 18:31 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/13 "2003-06-13T18:31:08Z")

</div>

> > > It seems to hold a copy of the reference…
> > 
> > No, it doesn’t. When you do a:
> 
> Sorry, but in fact you’re wrong. The reference is copied indeed.
> 
> > a = “Hello world, nice to meet you!”.split(’ ')  
> > a.each { |word| word = “lala” }  
> > p a  
> > [“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]
> > 
> > You’re binding word to a different object, not changing the objects  
> > themselves.
> 
> Binding “word” to another object is indeed done by copying the reference  
> to the other object. Or in other terms, after this assignment there is  
> one more reference to the object.

I think part of the confusion is the way other  
languages do things.

In C++, for example, assignment is a method,  
and a reference is an lvalue. So if you pass  
in a reference and assign to it, you do indeed  
change the object referred to.

In Ruby, assignment is not a method, and an  
object reference is not an lvalue.

Hal

> **···**
>
> ----- Original Message -----  
> From: “Robert Klemme” [bob.news@gmx.net](mailto:bob.news@gmx.net)  
> Newsgroups: comp.lang.ruby  
> To: “ruby-talk ML” [ruby-talk@ruby-lang.org](mailto:ruby-talk@ruby-lang.org)  
> Sent: Friday, June 13, 2003 5:31 AM  
> Subject: Re: does each work on a copy?

---

<div class="post-metadata">

**Author:** ![Jason\_Creighton1](https://avatars.discourse-cdn.com/v4/letter/j/ecc23a/32.png) [@Jason\_Creighton1](https://rubytalk.org/u/Jason_Creighton1)\
**Post date:** [13 June 2003 22:58 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/14 "2003-06-13T22:58:34Z")

</div>

> “Jason Creighton” [androflux@remove.to.reply.softhome.net](mailto:androflux@remove.to.reply.softhome.net) schrieb im  
> Newsbeitrag  
> [news:20030612123014.33a6449b.androflux@remove.to.reply.softhome.net](mailto:news:20030612123014.33a6449b.androflux@remove.to.reply.softhome.net)…
> 
> > > > remember that pretty much everything is a reference and you won’t go  
> > > > far  
> > > > wrong
> > > 
> > > I thought so, until this happened!  
> > > The array was full of references, so I thought el held the  
> > > reference from the Array.
> > > 
> > > It seems to hold a copy of the reference…
> > 
> > No, it doesn’t. When you do a:
> 
> Sorry, but in fact you’re wrong. The reference is copied indeed.

It looked as if the OP thought that ‘word’ was a “copy” (ie, object.dup), not  
a  
reference to the same object in the Array. Sorry, I could have phrased that  
better.

> > a = “Hello world, nice to meet you!”.split(’ ')  
> > a.each { |word| word = “lala” }  
> > p a  
> > [“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]
> > 
> > You’re binding word to a different object, not changing the objects  
> > themselves.
> 
> Binding “word” to another object is indeed done by copying the reference  
> to the other object. Or in other terms, after this assignment there is  
> one more reference to the object.

Right: We’re not modifing whatever objects were “in” (In the sense that the  
Array contains references to objects) the Array: We’re creating a new object  
(“lala”) and making word refer to that object. Had we done a word.upcase!,  
that would have modified the object in the array.

> a=“foo” # one ref to “foo”  
> b=b # two refs to “foo”  
> a=nil # one ref to “foo”  
> b=nil # zero refs to “foo”
> 
> I think you did want to say the right thing but mixed up terms a little.

Obviously. 🙂

> Maybe Perl has contributed to the confusion since it in fact does some  
> aliasing of references in arrays on function invocations the allow a  
> function to change array element references directly by simply assigning.  
> IMHO the ruby way is much cleaner and easier to understand.

Once you get used to it: I had used Python before, which basically does the  
same thing as Ruby, so it wasn’t a big shock for me.

Jason Creighton

> **···**
>
> On Fri, 13 Jun 2003 10:42:55 +0200 “Robert Klemme” [bob.news@gmx.net](mailto:bob.news@gmx.net) wrote:
> 
> > > On Thu, 12 Jun 2003 23:14:37 +0900 \> \> Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:

---

<div class="post-metadata">

**Author:** ![HAL\_9000](https://avatars.discourse-cdn.com/v4/letter/h/90ced4/32.png) [@HAL\_9000](https://rubytalk.org/u/HAL_9000)\
**Post date:** [13 June 2003 23:38 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/15 "2003-06-13T23:38:03Z")

</div>

> By ‘copy of the reference’ I meant:
> 
> ary = %w( a b c d e)  
> ary.each { |r| r = “X” }
> 
> r is given a copy of the ‘reference’ (apology for the Perlism),  
> so when you point (ugh, and the Cism) r at “X” you’re updating a  
> copy of the reference, not the original reference. Is that about right?

It’s right “in effect,” but you’re looking at it  
a little differently from the way we do here.

I wouldn’t ever use the term “copy of a reference”  
in describing Ruby’s behavior.

Remember that assignment is _not_ an operation on  
an object! It’s an operation on a variable.

This may confuse those who come from C++. As for  
Perl, I don’t really know it.

True, a variable “is a reference to an object.” But  
when you assign to a variable, you’re just assigning  
to a variable; you’re not “assigning to a reference.”  
It doesn’t affect the object referred to at all.

A “reference” is not a “real thing,” just a statement  
of a relationship, if you know what I mean.

Any assignment “overwrites” the reference that the  
variable had before, but does not affect the object.

Just think in terms of variables and objects. You can  
change a variable, and you can change an object. When  
you change an object, you are typically changing its  
contents.

> And in the below code,
> 
> string2 = “Hi”  
> is just pointing string2 to a new object, whereas  
> string2[0] = “J”  
> is editing the object through the string2 reference, just  
> as word.upcase! below is doing, as opposed to the |el| el = SPACE  
> in my original post.

Again I’d have to say “yes and no.”

An additional subtlety for the newbie is that, while  
string[0] = “J”  
_looks_ like an assignment, it really isn’t. I’m not  
kidding you here.

The String class has method methods called and =.  
The latter is named and invoked in such a way that it  
reminds us of assignment; but it’s really a method call  
on an object. (I said this last week in another context.)

Imagine that these were instead named ‘get’ and ‘set’ –  
instead of saying  
x = str[0]  
str[0] = y  
we could say  
x = str.get(0)  
str.set(0,y)

This makes it clearer that we are actually invoking a  
method on an object, not assigning to a variable.

Invoking a method on an object can potentially change  
that object. Assigning to a variable never changes the  
onject that the variable referred to before the  
assignment.

As an aside, consider why Ruby does not have C’s ++  
operator. It looks like an operator (as we’re used to  
thinking of it that way in C).

This is slightly different from other arguments I’ve  
heard on this topic. I’m making it up as I go along,  
so bear with me. 🙂

But if x++ means x = x + 1, then it’s just syntax sugar  
for assignment; it’s not an operator.

To have ++ as a method/operator that acts on an object  
makes no sense in Ruby (for numbers at least).

A number in Ruby is an object, but it is stored as an  
immediate value. Conceptually there is only one 5 value  
in the whole universe. It’s not like strings:

a = b = “Hello” # a and b refer to the same object  
c = “Hello” # c refers to a different object

d = e = 5 # d, e, and f all refer to the  
f = 5 # same object, 5

A ++ _could_ be implemented in Ruby as syntax sugar for  
assignment (though I don’t think Matz would ever do it).

It couldn’t be implemented as an operator/method (most  
operators in Ruby are really methods). Imagine that we  
set x to 5, and then did an x++. Now we have changed  
the _object_ 5 to the object 6! Our universe now has  
two 6’s and no 5’s. This is complete and utter nonsense,  
unless you have followed Alice down the rabbit hole.  
(Not that there’s anything wrong with that in general,  
but it doesn’t improve Ruby.)

Hal

> **···**
>
> ----- Original Message -----  
> From: “Rasputin” [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu)  
> To: “ruby-talk ML” [ruby-talk@ruby-lang.org](mailto:ruby-talk@ruby-lang.org)  
> Sent: Friday, June 13, 2003 6:01 PM  
> Subject: Re: does each work on a copy?

---

<div class="post-metadata">

**Author:** ![Jason\_Creighton1](https://avatars.discourse-cdn.com/v4/letter/j/ecc23a/32.png) [@Jason\_Creighton1](https://rubytalk.org/u/Jason_Creighton1)\
**Post date:** [14 June 2003 04:19 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/16 "2003-06-14T04:19:32Z")

</div>

Yes, that’s about right. If the following code makes sense, then you probably  
understand what’s going on.

ary = %w(a b c d e) # =\> [“a”, “b”, “c”, “d”, “e”]  
x = ary[0] # =\> “a”  
ary[0].id # =\> 537767284  
x.id # =\> 537767284  
x = “X” # =\> “X”  
x.id # =\> 537766974  
ary # =\> [“a”, “b”, “c”, “d”, “e”]

Jason Creighton

> **···**
>
> On Sat, 14 Jun 2003 08:01:40 +0900 Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:
> 
> > - Jason Creighton [androflux@remove.to.reply.softhome.net](mailto:androflux@remove.to.reply.softhome.net) [030612 19:44]:
> > 
> > > On Thu, 12 Jun 2003 23:14:37 +0900 \> \> Rasputin [rasputin@shrike.mine.nu](mailto:rasputin@shrike.mine.nu) wrote:
> > > 
> > > > > remember that pretty much everything is a reference and you won’t go  
> > > > > far wrong
> > > > 
> > > > I thought so, until this happened!  
> > > > The array was full of references, so I thought el held the  
> > > > reference from the Array.
> > > > 
> > > > It seems to hold a copy of the reference…
> > > 
> > > No, it doesn’t. When you do a:
> > > 
> > > a = “Hello world, nice to meet you!”.split(’ ')  
> > > a.each { |word| word = “lala” }  
> > > p a  
> > > [“Hello”, “world,”, “nice”, “to”, “meet”, “you!”]
> > > 
> > > You’re binding word to a different object, not changing the objects  
> > > themselves. If you did this:
> > 
> > By ‘copy of the reference’ I meant:
> > 
> > ary = %w( a b c d e)  
> > ary.each { |r| r = “X” }
> > 
> > r is given a copy of the ‘reference’ (apology for the Perlism),  
> > so when you point (ugh, and the Cism) r at “X” you’re updating a  
> > copy of the reference, not the original reference. Is that about right?

---

<div class="post-metadata">

**Author:** ![Rasputin1](https://avatars.discourse-cdn.com/v4/letter/r/439d5e/32.png) [@Rasputin1](https://rubytalk.org/u/Rasputin1)\
**Post date:** [16 June 2003 11:46 UTC](https://rubytalk.org/t/does-each-work-on-a-copy/6347/17 "2003-06-16T11:46:43Z")

</div>

- Hal E. Fulton [hal9000@hypermetrics.com](mailto:hal9000@hypermetrics.com) [0638 00:38]:

> > so when you point (ugh, and the Cism) r at “X” you’re updating a  
> > copy of the reference, not the original reference. Is that about right?

> Remember that assignment is _not_ an operation on  
> an object! It’s an operation on a variable.

> Just think in terms of variables and objects. You can  
> change a variable, and you can change an object. When  
> you change an object, you are typically changing its  
> contents.

I think you s/reference/variable/ on my ramblings, then that  
large clanking noise is the penny dropping. Thanks a lot.

> string[0] = “J”  
> _looks_ like an assignment, it really isn’t. I’m not  
> kidding you here.

Yeah, that was the moment I relaised i wasn’t in Kansas anymore 🙂

[the following deserves any entry in the FAQ IMO]

> As an aside, consider why Ruby does not have C’s ++  
> operator.

Thanks again, very useful.

> **···**
>
> > ----- Original Message -----
> 
> –  
> Never underestimate the power of a small tactical nuclear weapon.  
> Rasputin :: Jack of All Trades - Master of Nuns
