Is Ruby pass-by-reference or pass-by-value?

Jun 26, 2018 - 3 min read
Is Ruby pass-by-reference or pass-by-value?
Share

As you learn your way through Ruby’s OOP, you will eventually stumble upon the concept of object passing. It might not be very clear if Ruby uses pass-by-reference or pass-by-value to send objects to a method. So I’m going to explain how all that works.

What is pass-by-reference?

Pass-by-reference means that the arguments of a method are references to the variables that were passed into the method, and modifying the arguments modifies the original variables.

val = "Hello"

def my_method(arg)
  arg = "Hi"
end

my_method(val)
puts val # => In pass-by-reference the result would be "Hi"

If Ruby were pass-by-reference, changing the value of the argument (arg) would change the value of the variable val. That is because in pass-by-reference, arg is a reference, a memory address. It’s not the actual string "Hello".

What is pass-by-value?

On the other hand, pass-by-value means that the arguments of a method are the values of the variables that were passed into the method, and modifying the arguments does not modify the original variables.

val = "Hello"

def my_method(arg)
  arg = "Hi"
end

my_method(val)
puts val # => In pass-by-value the result would be "Hello"

What is a reference type?

There’s one more concept you need to understand before I can answer the main question. And that is about reference types.

A reference type is a type whose value is a reference to something else. Let me explain.

Reference Type

So when you pass the variable some_string to a method, the method receives a copy of some_string‘s value, which is a reference.

Pass By Value

As you can see in the image, what is passed into my_method is not a reference to some_string. It’s the value of some_string. But that value is actually a reference to the Hey There! object.

That means that if you were to modify arg, the changes would be seen by some_string, because they are both refering the same object in memory.

Example:

some_string = "Hey There!"

def my_mehtod(arg)
  # Changing the value of `arg`
  arg = "Hello!"
end

my_mehtod(some_string)

puts "The value of some_string is: #{some_string}"
# => The value of some_string is: Hey There!

Now, let’s change the behavior of my_method to modify the object that it references.

some_string = "Hey There!"

def my_mehtod(arg)
  # Changing the value of the object it references
  arg.gsub!(/Hey/, "Hi")
end

my_mehtod(some_string)

puts "The value of some_string is: #{some_string}"
# => The value of some_string is: Hi There!

See what happened there? By changing the actual string that arg was refering to, made it visible to some_string because we changed the object that both arg and some_string refer to.

So is Ruby pass-by-reference or pass-by-value?

As you can see from the examples above, what is actually passed into the method is the value. But that value is actually a reference. So even though the terminology is confusing, I would say Ruby is pass-by-value, but all the values are references.

12 Project Ideas
Cezar Halmagean
Speaker, Founder, Consultant with over 16 years of experience in helping growing SaaS companies scale large Ruby on Rails applications. Has written about the process of building Ruby on Rails applications in RubyWeekly, SemaphoreCI, and Foundr.
This website uses cookies to improve user experience. By using our website you consent to all cookies in accordance with our Cookie Policy.