# Functions, arguments and changing their value permantently

**URL:** <https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740>\
**Category:** Ruby\
**Created:** [March 24, 2008, 9:12am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740 "2008-03-24T09:12:24Z")\
**Posts on this page:** 9\
**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:** [March 24, 2008, 9:12am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/1 "2008-03-24T09:12:24Z")

</div>

Im coming over to Ruby from C++ after a long break from programming. One  
thing im having to get used to is how ruby references or points directly  
to variables. In C++ I can pass a variable as an argument to a function  
and then change the value within the function. This change will be  
reflected outside of the function. How do i go about doing this in ruby?

i.e.

x = 10

def changeit var  
var = 20  
end

changeit x  
puts x  
==\> 20

---

<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:** [March 24, 2008, 9:46am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/2 "2008-03-24T09:46:51Z")

</div>

x = changeit x

---

<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:** [March 24, 2008, 10:00am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/3 "2008-03-24T10:00:54Z")

</div>

On Mar 24, 9:46 am, Eder Quiñones [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> x = changeit x

You can easily return multiple arguments (x, y = changeit(x, y)) which  
makes the inout semantics rather obsolete (with a few exceptions where  
macro would be desirable). Some classes also provide destructive  
methods that can be used to replace it’s contents while maintaining  
the object’s identity.

---

<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:** [March 24, 2008, 10:22am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/4 "2008-03-24T10:22:37Z")

</div>

On Monday 24 March 2008, Adam A. wrote:

> def changeit var  
> var = 20  
> end
> 
> changeit x  
> puts x  
> ==\> 20

In ruby you pass the object to the method, not a reference to the  
variable.  
This means that, if you change the object, changes will affect every  
variable  
which contains the object. On the other hand, changing the object  
contained in  
the argument of the method (that is, writing var = 20) won’t affect any  
other  
variable. This means that if some classes are unchangeable (such as all  
kind  
of numbers and symbols), you can’t do what you want. Other classes  
provide  
methods which change them in place. As I said, such changes will affect  
every  
variable which points to the object. Here are some examples which should  
make  
things clearer:

def m1 str  
str.upcase  
end

def m2 str  
str = “a string”  
end

def m3 str  
str.upcase!  
end

x = “test”

m1 x  
puts “After m1 x is: #{x}”

m2 x  
puts “After m2 x is: #{x}”

m3 x  
puts “After m3 x is: #{x}”

The output is:

After m1 x is: test  
After m2 x is: test  
After m3 x is: TEST

m1 calls String#upcase, which is a non-destructive method (that is, a  
method  
which doesn’t change its receiver) and does nothing else. Of course,  
this  
doesn’t change x.

m2 sets the local variable str, which initially contains the argument  
passed  
to the method, to a different value, “a string”. In C++, if the argument  
was a  
reference, this would have also set x to “a string”. In ruby it doesn’t.

m3 calls a destructive method on str. A destructive method changes its  
receiver, so the contents of the object contained by str change (notice  
that  
this is different from the previous case, where a new object was put  
into  
str). Since str and x contain the same object, x also changes. A method  
like  
this can be used to achieve the result you wanted, but it can be written  
only  
if the argument has a destructive method which does what you need (for  
example, you couldn’t have done the same for an Integer, since it  
doesn’t have  
destructive methods).

I hope this helps

Stefano

---

<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:** [March 24, 2008, 10:14am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/5 "2008-03-24T10:14:22Z")

</div>

On Mon, Mar 24, 2008 at 3:12 AM, Adam A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> def changeit var  
> var = 20  
> end
> 
> changeit x  
> puts x  
> ==\> 20

Ruby tries to maintain scope rigidly. So your x before will not  
change within the scope of the method changeit.

Your method, when called, says…

changeit 10

Then you want to do assignment as…

x = 20

It’s a different x!

You can pull out of local scope with class instance variables or  
globals. Your same code, just changed…

@x = 10

def changeit n  
@x = n  
end

…or return it directly form the method if that’s the only value you  
need

x = 10

def changeit n  
n  
end

x = changeit

…in which case you would probably want to rename the method.

I have to say, I don’t see this as a good design pattern using Ruby,  
but I don’t know what you’re trying to do 🙂

I can’t tell by your post, but if really what you want to do is send a  
variable “name” into the method and have the method change the value.  
That’s different and might require some brainiacs on the list to help  
you (my guess is that you would have use some form of #eval).

Todd

---

<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:** [March 24, 2008, 11:57am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/6 "2008-03-24T11:57:41Z")

</div>

On 3/24/08, Adam A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Im coming over to Ruby from C++ after a long break from programming. One  
> thing im having to get used to is how ruby references or points directly  
> to variables. In C++ I can pass a variable as an argument to a function  
> and then change the value within the function. This change will be  
> reflected outside of the function. How do i go about doing this in ruby?

Perhaps something here can help you get your head around this aspect  
of how Ruby isn’t C++:

## [http://talklikeaduck.denhaven2.com/articles/2006/09/13/on-variables-values-and-objects](http://talklikeaduck.denhaven2.com/articles/2006/09/13/on-variables-values-and-objects) [http://talklikeaduck.denhaven2.com/articles/2008/02/08/whose-variable-is-it-anyway](http://talklikeaduck.denhaven2.com/articles/2008/02/08/whose-variable-is-it-anyway)

Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<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:** [March 25, 2008, 12:12am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/7 "2008-03-25T00:12:42Z")

</div>

Sorry I missed this reply

You can easily return multiple arguments (x, y = changeit(x, y)) which  
makes the inout semantics rather obsolete (with a few exceptions where  
macro would be desirable). Some classes also provide destructive  
methods that can be used to replace it’s contents while maintaining  
the object’s identity.

which answers my question. Between reading the posts and replying I had  
a good nights sleep and still a bit groggy.

---

<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:** [March 25, 2008, 12:25am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/8 "2008-03-25T00:25:34Z")

</div>

On Tue, 25 Mar 2008 08:06:38 +0900, Adam A.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thank you so much for all of your detailed replies. Some of you asked  
> why I wanted to do this and why don`t I just return the value to the  
> variable I want to change ala x = doit x
> 
> Well actually my function changes 2 values. Functions can only pass one  
> back so I thought I`d pass one as an argument as well. Is that bad  
> programming design? What are other options?

You could have the function return multiple values as an array:

def foo(x, y)  
[x + y, x \* y]  
end

sum, product = foo(2, 3)  
puts sum  
puts product

-mental

---

<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:** [March 25, 2008, 12:06am UTC](https://www.ruby-forum.com/t/functions-arguments-and-changing-their-value-permantently/132740/9 "2008-03-25T00:06:42Z")

</div>

Thank you so much for all of your detailed replies. Some of you asked  
why I wanted to do this and why don`t I just return the value to the  
variable I want to change ala x = doit x

Well actually my function changes 2 values. Functions can only pass one  
back so I thought I`d pass one as an argument as well. Is that bad  
programming design? What are other options?

Many thanks
