Ruby, pass by value or by reference?

 Apr, 21 - 2009   38 comments   Ruby

It’s a basic question that I myself had a problem with when i started using Ruby: Does Ruby pass by value or by reference?
Well, if you want a direct answer, then: Ruby passes by value. It’s a similar behavior of what Java does.

Let’s prove it via examples:
Update: this example was passing integers, and it turned out that even everything in ruby is an object, but immedaite values are passed directly by their values, so i changed this example to let it pass strings instead.

Let’s pass an argument to a method and check what goes on:

As you see, we defined a method ‘change’ that takes a parameter ‘x’, changes it value and then returns it back. Then we invoked that method on the argument ‘y’ which had the value ’3′, and kept having the same value after the method invocation.
This simple example proves that the argument is not passed by reference, otherwise the value of ‘y’ would rather changed to ’10′ after the method invocation.

Now let’s take another example:

In this example, the passed argument value ‘hello’ has changed to ‘fello’, and thus it proves that the argument is not passed by value, otherwise the value of ‘s’ would kept having the same value ‘hello’.

Thus it’s not by value, neither by reference, then what is it?

As you know, everything in Ruby is an object, and thus, doing:

means: assign a reference(a place in memory that points to referenced value. In other words, it’s a place that holds the memory address of the referenced value) of the string ‘somthin’ to the variable named ‘val’, and normally when working with the variable ‘val’, it means we are working on it’s referenced object ‘smthing’.

But when invoking a method:

Things change a bit, as Ruby passes a copy of the ‘val’ reference itself(which is the memory address of the referenced object), not it’s referenced object, to the method Foo, and that copy will still reference the same object ‘smthing’ as the variable ‘val’ does.
This is called: Pass by Value, a copy of a reference to an object is passed, and so, not the referenced object itself is passed, neither the argument itself.
Then Ruby passes by value. Some ppl like to call it “pass by reference value”, but that’s not standard afaik.

That explains what goes in both examples, as in the first example the value of the argument ‘y’ didn’t change due to the fact that we are not passing the reference ‘y’ itself, instead a copy of it, and thus, when its copy referenced another object(via assignment operator), the original variable ‘y’ kept referencing it’s object, the object with value ’3′ in our case. As for the second example, the argument ‘s’ changed due to the fact that its passed copy is still referencing the same object ‘hello’, but the operator [] changed the referenced object value, and thus got a new value ‘fello’.

I hope the idea is clear now, if not, please don’t hesitate to comment.

Update:
I have blogged a new article explaining passing by reference and value in 3 languages c++, java and ruby