On Monday 24 March 2008, Adam Akhtar 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?
>
> i.e.
>
> x = 10
>
> 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