There has been a debate over the Internet about whether Ruby's method parameters are passed by value or by reference. Some people claim that it's passed by value by providing the following code.
str_1 = "pass_by_value" def pass_by_value(str) str = "pass_by_reference" end pass_by_value(str_1) str_1 => "pass_by_value"
It looks convincing at the first glance, as the function pass_by_value didn't change the value of the str_1. But if you change the code a little bit, you will find this assertion is erroneous.
str_1 = "pass_by_value" str_1.object_id => 70332873209820 def pass_by_value(str) puts str.object_id end pass_by_value(str_1) 70332873209820 => nil
Now we can come to the conclusion that Ruby does not pass argument by value, but neither does it pass argument by reference. Because if it does, str_1 should've been changed in our first code snippet. So there must be another evaluation strategy that Ruby uses. This third evaluation strategy is called pass by sharing. Here is a citation from wikipedia that states how pass by sharing works. The semantics of call by sharing differ from call by reference in that assignments to function arguments within the function aren't visible to the caller (unlike by reference semantics)[citation needed], so e.g. if a variable was passed, it is not possible to simulate an assignment on that variable in the caller's scope. However since the function has access to the same object as the caller (no copy is made), mutations to those objects, if the objects are mutable, within the function are visible to the caller, which may appear to differ from call by value semantics. Let's take a look at the following code snippet.
str_1 = 'abc' str_2 = 'abc' def mutate_str(str) str << 'efg' end def assign_str(str) str = 'abcefg' endAnd if we call mutate_str on str_1 and assign_str on str_2. We can find that str_1 is changed to 'abcefg', while str_2 remains 'abc'.
> mutate_str(str_1) => "abcefg" > str_1 => "abcefg" > assign_str(str_2) => "abcefg" > str_2 => "abc"