# Loser question

**URL:** <https://www.ruby-forum.com/t/loser-question/118336>\
**Category:** Rails\
**Created:** [October 25, 2007, 8:23pm UTC](https://www.ruby-forum.com/t/loser-question/118336 "2007-10-25T20:23:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 25, 2007, 8:23pm UTC](https://www.ruby-forum.com/t/loser-question/118336/1 "2007-10-25T20:23:49Z")

</div>

Ok. I’m a loser. I’ve been told and warned. But I still got bit.

If I do:

irb(main):001:0\> GOLF = [1, 2, 3]  
=\> [1, 2, 3]  
irb(main):002:0\> g = GOLF  
=\> [1, 2, 3]  
irb(main):003:0\> g \<\< 4  
=\> [1, 2, 3, 4]  
irb(main):004:0\> g  
=\> [1, 2, 3, 4]  
irb(main):005:0\> h = GOLF  
=\> [1, 2, 3, 4]

Notice that h is [1, 2, 3, 4] and GOLF has changed its value.

I understand why. Thats not my question.

My question is what or how do most ruby people do this?

Do you simply do this:

irb(main):001:0\> GOLF = [1, 2, 3]  
=\> [1, 2, 3]  
irb(main):002:0\> g = GOLF.dup  
=\> [1, 2, 3]  
irb(main):003:0\> g \<\< 4  
=\> [1, 2, 3, 4]  
irb(main):004:0\> h = GOLF  
=\> [1, 2, 3]

Or, do you usually hide GOLF inside a method – which does the dup. How  
is this handled most of the time?

Thank you very much,  
pedz

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 25, 2007, 8:42pm UTC](https://www.ruby-forum.com/t/loser-question/118336/2 "2007-10-25T20:42:34Z")

</div>

On 10/25/07, Perry S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Ok. I’m a loser. I’ve been told and warned. But I still got bit.

Man, you’re too hard on yourself!

> =\> [1, 2, 3, 4]
> 
> is this handled most of the time?  
> If you want GOLF to be immutable, you can freeze it:

$ irb --simple-prompt

> > GOLF = [1, 2, 3]  
> > =\> [1, 2, 3]  
> > GOLF.freeze  
> > =\> [1, 2, 3]  
> > h = GOLF  
> > =\> [1, 2, 3]  
> > h \<\< 4  
> > TypeError: can’t modify frozen array  
> > from (irb):4:in `\<\<’  
> > from (irb):4  
> > from :0

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 25, 2007, 10:10pm UTC](https://www.ruby-forum.com/t/loser-question/118336/3 "2007-10-25T22:10:59Z")

</div>

I would say that it depends on the context. If this is something you  
will do often, make a function out of it to keep things DRY, but if it’s  
just once or twice , do it inline. Since we are not talking about a  
large number of lines of code and the intent is fairly obvious, it  
really doesn’t matter too much.

my $.02  
-Bill

Michael G. wrote:

> –Michael
> 
> >

–  
Sincerely,

William P.

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 25, 2007, 8:49pm UTC](https://www.ruby-forum.com/t/loser-question/118336/4 "2007-10-25T20:49:00Z")

</div>

I have a lot of functions that do things like this:

I have a function that takes an array, and sets various additional  
"default’ values in it. I first clone what is passed in:

newvals = args.clone

and then modify newvals.

I assume .dup and .clone are about the same?

–Michael

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 26, 2007, 10:16am UTC](https://www.ruby-forum.com/t/loser-question/118336/5 "2007-10-26T10:16:13Z")

</div>

On 10/25/07, Perry S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> =\> [1, 2, 3, 4]  
> irb(main):004:0\> g  
> =\> [1, 2, 3, 4]  
> irb(main):005:0\> h = GOLF  
> =\> [1, 2, 3, 4]
> 
> Notice that h is [1, 2, 3, 4] and GOLF has changed its value.

Not really, GOLF still points to the same array.

The array _is_ mutable though, and you may want to freeze it as others  
have pointed out.

Sincerely,  
Isak

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 26, 2007, 2:17am UTC](https://www.ruby-forum.com/t/loser-question/118336/6 "2007-10-26T02:17:06Z")

</div>

I’m not quite sure what you’re driving at here. Were you expecting  
different behavior than what you showed in your original post? I mean,  
if h and g are references to the same object, of course modifying the  
object will have a same result no matter which reference you use to  
“view” the object.

If your end goal is to create references to two different objects (by  
object identity) that begin life with the same contents, then it’s  
very common in object oriented programming languages to clone (dup)  
the object. Any other behavior than this would be “odd” at best, and  
would completely confuse every object oriented programmer out there.

Here is an example of how a language other than Ruby would support  
this. The following is a “factory” method used to construct a new  
array using the contents of another array written in Objective C:

- (id)arrayWithArray:(NSArray \*)anArray

Here the + indicates that this is a class method returning an array  
constructed using a reference to a different array. The array returned  
by this method references an new array and does not simply reference  
the original array.

Ruby doesn’t actually have this type of factory method, but if you do  
this a lot it could be easily added to the Array class. But, is that  
really worth it when all you need is:

g = h.dup

---

<div class="post-metadata">

**Author:** ![pedz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/839c29/32.png) [@pedz](https://www.ruby-forum.com/u/pedz)\
**Post date:** [October 26, 2007, 5:23pm UTC](https://www.ruby-forum.com/t/loser-question/118336/7 "2007-10-26T17:23:19Z")

</div>

I started doing this:

GOLF = [1, 2, 3].freeze

Now GOLF can’t change and what it points to can’t change and it is  
reasonably compact and somewhat obvious.

irb(main):032:0\> S = [1, 2, 3, 4].freeze  
=\> [1, 2, 3, 4]  
irb(main):033:0\> h = S  
=\> [1, 2, 3, 4]  
irb(main):034:0\> h \<\< 8  
TypeError: can’t modify frozen array  
from (irb):34:in `\<\<’  
from (irb):34  
from :0  
irb(main):035:0\> S = 8  
(irb):35: warning: already initialized constant S  
=\> 8
