I think the value/reference stuff in Ruby is similar to Java: Variables are always references to objects (in Ruby everything is an object).
That means when you assign a variable to an object, you can imagine the variable as an arrow that points to the object. If you have a = b = _some_object_, that’s like having two arrows both pointing to the same object.
a = b = _some_object_
Re-assigning a variable, e.g. a = _some_other_object_, just points the arrow to another object. It doesn’t change the object it was pointing to before. On the other hand, dereferencing the variable, e.g. a.x = _something_, changes the underlying object. That means the change is visible to any variable pointing to the same object. If you don’t want this behavior, you have to explicitly make a copy of the object before you make a change to it.
a = _some_other_object_
a.x = _something_
Lastly, when you pass a variable to a function, a copy of the reference is made. That means there’s one arrow pointing to the object in the calling function and another arrow pointing to the same object in the called function. Since a copy is made, we say the argument is passed by value. But keep in mind that the argument is a reference (an arrow), so we are passing references by value.
One more note: You can create so-called “immutable” objects. That just means that methods that modify such objects will actually create a copy. The original object remains unchanged and instead a new object is created with the desired modification. As I mentioned earlier, creating copies like this can make it seem you’re dealing with values rather than references. Primitive objects like integers, e.g. 3, are immutable. That’s why doing 3 + 3 doesn’t change what 3 means, which of course would be bad!
3 + 3
See also: shallow vs. deep copy
Thanks for chiming in! This was really helpful Nested. 🙌
We’re a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.