# How to avoid passing by reference and how to copy objects

**URL:** <https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982>\
**Category:** Ruby\
**Created:** [August 27, 2008, 9:15am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982 "2008-08-27T09:15:29Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 27, 2008, 9:15am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/1 "2008-08-27T09:15:29Z")

</div>

Hi after a bit of searching and reading im quite confused by this.

I first learnt C so used to being able to pass by reference or by value.  
In Ruby its just by reference (so ive just found out after an hour of  
chasing a bug).

I have an array of ojbects which are baisically acting like structures.  
I want to pass the array to a function. This function will take the  
array, make a new copy so as to protect the original from any changes.  
Changes will be made to the copy and then the copy is returned.

How do i do that?

Ive looked dup but i dont think it works for objects… isnt there a  
method to copy an object (i.e make new space in memory and put the data  
there rather than juts pointing to the original objects address).

Id have thought it was necessary if you can only pass by reference…or  
is the above considered bad design practice in ruby?

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 27, 2008, 9:27am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/2 "2008-08-27T09:27:15Z")

</div>

On Wed, Aug 27, 2008 at 9:10 AM, Adam A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> How do i do that?

The problem with the above approach is that an array holds also  
references  
to the contained objects. So if you are changing what objects the array  
contains  
your approach is fine. If you are changing the contained objects  
themselves, then  
you have the same problem, since dup makes a shallow copy:

irb(main):001:0\> a = %w{one two three}  
=\> [“one”, “two”, “three”]  
irb(main):002:0\> a.map {|x| x.object\_id}  
=\> [-606229548, -606229578, -606229608]  
irb(main):003:0\> b = a.dup  
=\> [“one”, “two”, “three”]  
irb(main):004:0\> b[0] = “new value”  
=\> “new value”  
irb(main):005:0\> a  
=\> [“one”, “two”, “three”]  
irb(main):006:0\> b  
=\> [“new value”, “two”, “three”]  
irb(main):007:0\> b.map {|x| x.object\_id}  
=\> [-606260528, -606229578, -606229608]

As you can see here, both a and b are referencing the same  
string objects in their second and third position. So the strings  
“two” and “three” are the same objects in both arrays. If you  
change _those objects_ the change will be reflected in both  
arrays:

irb(main):008:0\> a[2].upcase!  
=\> “THREE”  
irb(main):009:0\> a  
=\> [“one”, “two”, “THREE”]  
irb(main):010:0\> b  
=\> [“new value”, “two”, “THREE”]

If you want to avoid this, you need b to be a deep copy of a.  
One way to achieve it is with Marshal:

irb(main):011:0\> c = Marshal.load(Marshal.dump(a))  
=\> [“one”, “two”, “THREE”]  
irb(main):012:0\> c.map {|x| x.object\_id}  
=\> [-606348068, -606348078, -606348088]  
irb(main):014:0\> a[2].downcase!  
=\> “three”  
irb(main):015:0\> a  
=\> [“one”, “two”, “three”]  
irb(main):016:0\> b  
=\> [“new value”, “two”, “three”]  
irb(main):017:0\> c  
=\> [“one”, “two”, “THREE”]

Although you should read a bit more on Marshal to understand if  
it suits your needs.

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 27, 2008, 9:35am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/3 "2008-08-27T09:35:29Z")

</div>

Adam A. wrote:

> Hi after a bit of searching and reading im quite confused by this.
> 
> I first learnt C so used to being able to pass by reference or by value.  
> In Ruby its just by reference (so ive just found out after an hour of  
> chasing a bug).
> 
> I have an array of ojbects which are baisically acting like structures.  
> I want to pass the array to a function. This function will take the  
> array, make a new copy so as to protect the original from any changes.  
> Changes will be made to the copy and then the copy is returned.
> 
> How do i do that?
> 
> Ive looked dup but i dont think it works for objects… isnt there a  
> method to copy an object (i.e make new space in memory and put the data  
> there rather than juts pointing to the original objects address).
> 
> Id have thought it was necessary if you can only pass by reference…or  
> is the above considered bad design practice in ruby?

Have a look at this post:  
[Ruby (Al2O3::Cr)](http://al2o3-cr.blogspot.com/2008/08/object-arr.html) it explains your  
case a bit.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 27, 2008, 7:10pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/4 "2008-08-27T19:10:55Z")

</div>

On 27.08.2008 09:10, Adam A. wrote:

> I first learnt C so used to being able to pass by reference or by value.  
> In Ruby its just by reference (so ive just found out after an hour of  
> chasing a bug).

Well, it’s actually an advantage because passing a reference is usually  
faster than passing an object by value.

> Id have thought it was necessary if you can only pass by reference…or  
> is the above considered bad design practice in ruby?

Adding to the excellent advice: depending on what you have in your  
structs you can also use Array#map to get a copy like this:

def f(x)  
copy = x.map {|el| el.dup}  
end

or even

def f(x)  
x.map do |el|  
# your calculation on each el  
YourStruct.new some, more, values, like, el.length + 1  
end  
end

As I said, whether it’s safe depends on your data.

But I fully agree to Brian’s remark that something like this (deep copy)  
is usually not done. It depends on your problem at hand which is the  
best approach so if you provide a little more detail we might be able to  
provide more concrete advice how to tackle your particular situation.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 27, 2008, 7:15pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/5 "2008-08-27T19:15:01Z")

</div>

Hi –

On Wed, 27 Aug 2008, Adam A. wrote:

> Hi after a bit of searching and reading im quite confused by this.
> 
> I first learnt C so used to being able to pass by reference or by value.  
> In Ruby its just by reference (so ive just found out after an hour of  
> chasing a bug).

I know this sounds pedantic, but I think it’s really pass by value,  
with the values being references.

In other words, if you do this:

a = [1,2,3]

you’re binding the identifier a to a reference to the array. If you  
then do:

puts a

you’re passing the value of a (which is a reference to an array) to  
puts.

In practical terms it doesn’t matter, but it helps make sense of, for  
example, the fact that you can’t pass a reference-by-reference.

David

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 7:43am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/6 "2008-08-28T07:43:07Z")

</div>

thanks everyone for that.

I typed along on irb to the examples presented and understand more about  
rubys behaviour with “copying” stuff.

Its basically like (probably IS under the hood) Pointers.  
so for some arrays a and b

a = b

thats basically copying the pointers themselves. So whatever changes i  
make in A will be reflected in B.

a = b.dup

create some NEW pointers but which point to the same memory space. If i  
edit one of the members it will be reflected in both a and b. However if  
i substitute it for a totally different member im guessing new memory  
space is allocated and a pointer points to that new memory space. Hence  
the change is reflected in only one array.

to get a copy where new memory space for duplicate objects is creted,  
you look towards marshall…

am i right (roughly) … hmmm pointers in C was always tricky.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 8:17am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/7 "2008-08-28T08:17:47Z")

</div>

thanks lex for that.  
Im going to search for “ruby program design principles” or patterns  
/best practices with regards to functions. When i learnt C (10 years ago  
so its rusty) I was told to use pass by reference only when necessary. I  
think the reason being bug tracking etc maybe the reasoning was similiar  
ot that of not to over/misuse global variables.

So switching to ruby where pass by reference is the only choice seems to  
be making my programming a little less smooth. Im just used to knowing  
that the original value wont be changed. Sure I could dup or clone  
everything but that seems to go against what ruby intends.

if anyone has a good link or book regarding such differences, their  
implications and how to design along them rather than against (i.e. best  
practice) please give us a shout. In the meantime ill go away and do  
some searching and rejig my code.

thanks

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 7:53am UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/8 "2008-08-28T07:53:17Z")

</div>

> create some NEW pointers but which point to the same memory space. If i  
> edit one of the members it will be reflected in both a and b. However if  
> i substitute it for a totally different member im guessing new memory  
> space is allocated and a pointer points to that new memory space. Hence  
> the change is reflected in only one array.
> 
> to get a copy where new memory space for duplicate objects is creted,  
> you look towards marshall…
> 
> am i right (roughly) … hmmm pointers in C was always tricky.

Here is a little example

class XTest

attr\_accessor :test

def initialize  
@test = 2  
end

end

first = XTest.new  
first.test = 10  
second = first.clone  
second.test = 11  
puts first.test

So , If you want to preserve your parameters , clone them.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 1:09pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/9 "2008-08-28T13:09:08Z")

</div>

Hi –

On Thu, 28 Aug 2008, Adam A. wrote:

> everything but that seems to go against what ruby intends.  
> See my earlier post, and Brian’s last one. It’s not pass by reference;  
> it’s pass by value, where the values are references. That’s actually  
> good news. For one thing, you don’t have to do (indeed can’t do)  
> pointer arithmetic. Every reference is exactly one step away from its  
> object. There are no references to references (which is why you can’t  
> do pass-by-reference in Ruby).

C is actually a poor point of reference (ha ha) for understanding Ruby  
variables and references, because the two are so different. I’d  
encourage you not to worry about how Ruby semantics align with C  
semantics, because they pretty much don’t. In C you have this:

```
***p ->** p -> *p -> p

```

but in Ruby you always have this:

```
     b
     |
     v

```

a-\> obj \<- c

```
     ^
     |
     d

```

David

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 1:32pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/10 "2008-08-28T13:32:49Z")

</div>

On Thu, Aug 28, 2008 at 1:03 PM, David A. Black [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> C is actually a poor point of reference (ha ha) for understanding Ruby  
> variables and references, because the two are so different. I’d  
> encourage you not to worry about how Ruby semantics align with C  
> semantics

Nevertheless C is only pass by value. That could help.

There’s no way in C to accomplish this

a = 7;  
some\_function(a);  
// a is 7 for certain here

You can pass the address of a:

a = 7;  
p = &a;  
some\_other\_function(p);  
// a may be 5 now

but note that the argument of the function is p, it is not a. So you  
are clearly just passing p by value.

Again, when some\_other\_function returns there’s no way p is pointing  
to anything that is not a, because of pass by value semantics. In some  
vague sense this second example has some resemblances to Ruby: you are  
always passing ps in Ruby so to speak (that’s an analogy, it is clear  
from the rest of the thread there are no actual pointers involved).

Through those ps, if the object is mutable you may change the state of  
the object, but cannot change the very reference, the object pointed  
at by p, the same way you cannot in C.

Java is pass by value as well.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 1:43pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/11 "2008-08-28T13:43:23Z")

</div>

On Thu, Aug 28, 2008 at 1:32 PM, Xavier N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> There’s no way in C to accomplish this
> 
> a = 7;  
> some\_function(a);  
> // a is 7 for certain here

Sorry I messed up the wording, I mean there’s no way some\_function can  
change the value of a in the caller.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [August 28, 2008, 1:51pm UTC](https://www.ruby-forum.com/t/how-to-avoid-passing-by-reference-and-how-to-copy-objects/146982/12 "2008-08-28T13:51:37Z")

</div>

Perl is only pass-by-reference by the way, sometimes it helps to see a  
pass-by-reference example. So in Perl you can do this:

sub some\_function { $\_[0] = 5 }

my $a = 7;  
some\_function($a);

# now $a is 5

Perl has references, but the “reference” in “pass-by-reference” is a  
different word, it means the parameters of the function are _aliases_  
of the arguments in the caller.
