0

I understand pass-by-value as passing a copy of an object into a method. When a programming language is pass-by-value, we can alter that object we passed into the method, but it leaves the original object that was passed in unaffected. This is because a copy is passed into the method as opposed to the actual object itself (or a reference to that object).

I understand pass-by-reference to mean passing a reference to the actual object. Therefore: if we pass a reference of an object into a method: then when we modify the object within that method (via the reference that was passed in) then the actual object gets changed, outside of the scope of the method.

Example:

class Dog
  attr_accessor :name
  def initialize()
    @name = "Denver"
  end
end

def rename_dog(dog)
  dog.name = "New_Dog_Name"
  return
end

dog = Dog.new
puts "Dog's initial name: #{dog.name}" # => Dog's initial name: Denver
rename_dog(dog)
puts "Dog's New name: #{dog.name}" # => Dog's New name: New_Dog_Name

To me: this makes it seem as though ruby is pass-by-reference. We pass a reference of the dog into the rename_dog(dog) method. Since it is a reference: we modify the actual dog object which is outside of the scope of the rename_dog(dog) method, which is reflected by the last puts statement.

This is as opposed to behavior I would expect if ruby was pass-by-value. If ruby was pass-by-value: I would expect that last puts statement to return the dog.name "Denver" as opposed to "New_Dog_Name".

Everywhere I look online though: everywhere says that ruby is pass-by-value. What am I getting wrong here?

Neil
  • 4,578
  • 14
  • 70
  • 155
  • 1
    http://stackoverflow.com/q/1872110/5647260 – Andrew Li Feb 14 '17 at 17:28
  • @AndrewLi I did happen to see that question. It does not really answer why the example above is `pass-by-value` as opposed to `pass-by-reference` in terms of how I understand the two concepts. – Neil Feb 14 '17 at 17:34
  • @Neil: In order to be a non-duplicate, I think you need to explain quite deeply "how I understand the two concepts" in your question. Your question stops being about Ruby at that point, and about understanding the finer details of what the concepts actually cover. Otherwise, I hope my pre-duplicate answer helps you at least a little. – Neil Slater Feb 14 '17 at 17:37
  • 1
    "I understand pass-by-reference to mean passing a reference to the actual object." – It means passing the *reference* (i.e. the *variable*) *instead* of the object. And *reference* here does not mean "pointer". It means something similar to what "lvalue" means in C. It means "variable, parameter, constant, some sort of binding, literal, …". "Since it is a reference: we modify the *actual* dog object" – The fact that you can modify the object is irrelevant. That's *mutable state* and is completely orthogonal to pass-by-reference. If you could modify the *reference*, then it would be p-b-ref. – Jörg W Mittag Feb 14 '17 at 19:18

1 Answers1

2

Ruby is strictly "pass by value" when you consider what a variable is. It is a pointer to an object. Ruby variables and method parameters can only be of these pointers.

Probably best shown by annotating your example:

# Define and set local variable 'dog' to a pointer to a new Dog object
dog = Dog.new
puts "Dog's initial name: #{dog.name}" # => Dog's initial name: Denver

# Pass the pointer, *by value* to the rename_dog method
rename_dog(dog)

puts "Dog's New name: #{dog.name}" # => Dog's New name: New_Dog_Name

Now you might say "this is a useless, technical, definition of pass by value". I would partially agree. It goes against expectations.

However, it only goes against expectations from languages where you have a choice between pointers to objects and variables which directly represent those objects. In Ruby you never have this choice. The definition of Ruby as pass-by-value is correct, but because everything is a pointer, you have to explicitly clone container objects - or use a method which returns a modified copy - if you want to work on a "separate value".

Neil Slater
  • 26,512
  • 6
  • 76
  • 94