I was convinced Ruby passes parameters by reference when you call a method. I knew there are some special cases (bool, symbols, fixnums, floats) when uses pass-by-value, but usually for objects by-reference is the default. Today I had a conversation on Stackoverflow about the topic and now I know the most object oriented languages (like C#, Java, Smalltalk) use pass-by-value, or more precisely pass-by-value-of-pointer.
In Ruby the variables are stored by uintptr_t VALUE
. VALUE can have special flags to determine it’s type. Special flags are small integer, symbol, true, false, nil, Qundef
. When no special flag is set, it stores a reference to an object. When you pass a parameter to a method, it passes the VALUE
by-value, so the reference to the object will be copied. Consider this behaviour it can be pass-by-reference, but it’s not.
In C++ when you pass an object by reference, you do something like this:
1 2 3 4 5 | void increase(int ¶m) { int d = param + 1; param = d; } |
void increase(int ¶m) { int d = param + 1; param = d; }
After calling increase
method with a value, the param
will be increased well.
1 2 3 | int num = 1; increase(num); // num == 2 |
int num = 1; increase(num); // num == 2
In Ruby because the VALUE
is passed by value, the previous C++ like implementation works different:
1 2 3 4 5 6 7 8 9 | def increase(param) d = param + 1 param = d end num = 1 increase(num) # num == 1 |
def increase(param) d = param + 1 param = d end num = 1 increase(num) # num == 1
param = d
in increase method will copy a new reference to the VALUE, so param
will reference a new object. After returning from increase both the d
and the new param
will be freed, and the original value of param
will be referenced by num
, 1.
So that’s why we say Ruby uses pass-by-value when calling a method with an object!
Leave Your Response