liveBook · Manning

Reference

As explained in The Well-Grounded Rubyist, Fourth Edition

An object reference is a value that identifies a Ruby object rather than containing an independent copy of that object.

Try assigning one string to two variables, then changing it through one of them. Both variables appear to change. Ruby has not copied the string: each variable holds a reference to the same object. Assigning one variable to another copies the reference, not the object. section 2.5.1

def say_goodbye
  str = "Hello"
  abc = str
  str.replace("Goodbye")
  puts str
  puts abc
end 
say_goodbye   

Here, `abc = str` gives both variables a reference to one string. `replace` changes that string in place, so both `puts` calls print `Goodbye`. section 2.5.1

Reassignment is different

With `str = "Hello"; abc = str; str = "Goodbye"`, `str` prints `Goodbye` but `abc` still prints `Hello`. The second assignment binds `str` to a different string; it neither changes the old string nor redirects `abc`. The same assignment rule applies beyond local variables. section 2.5.2

Method arguments also pass object references. If a method calls `replace` on its string argument, the caller can see the changed string afterward. Pass `s.dup` when the method should receive a separate object, or use `freeze` to prevent changes to an object. `clone` differs from `dup` when the original is frozen: the clone stays frozen. section 2.5.3

>> numbers = ["one", "two", "three"]
=> ["one", "two", "three"]
>> numbers.freeze
=> ["one", "two", "three"]
>> numbers[2] = "four"                     1
RuntimeError: can't modify frozen array    1
>> numbers[2].replace("four")      2
=> "four"
>> numbers
=> ["one", "two", "four"]       3

Freezing an array prevents replacing one of its elements, but does not freeze the strings it references. Changing an element’s string with `replace` remains possible. section 2.5.3

To check whether two variables identify one object, compare their objects’ `object_id` values. Two strings can display identical text yet be different objects. There are also exceptions to the usual reference explanation: Ruby handles certain values, including some integers, symbols, `true`, `false`, and `nil`, as immediate values. section 2.3.1 section 2.5.1

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Works through reference copying, reassignment, and argument behavior, while noting immediate-value exceptions without detailing their implementation.
Examples
Contrasts `replace` with reassignment, then tests a method argument and a mutable string inside a frozen array.
What it assumes
Assumes basic Ruby assignment and method calls, but builds the reference model from a string example.
What you can do after
Diagnose/debug with it when a mutation unexpectedly appears through another variable, and use `dup` or `freeze` to limit changes.
How it connects
Connects object references to object identity, mutation, method arguments, duplication, and freezing.

Also explained in

Compare how 17 books explain reference →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.