liveBook · Manning

Assignment

As explained in The Well-Grounded Rubyist, Fourth Edition

Assignment is the Ruby language operation that binds or updates an identifier with a reference to an object.

A value to use later

In irb, `days = 365` prints `365`. The assignment binds `days` so it can be used later, and the assignment expression itself evaluates to its right-hand side. Thus `days * 24 * 60` evaluates to `525600`. section 1.4.2

For most objects, a variable holds a reference, not the object's contents. After `str = "Hello"` and `abc = str`, both names refer to the same string. Calling `str.replace("Goodbye")` changes that string, so reading either variable yields `"Goodbye"`. Some objects, notably integers, are stored as immediate values instead. section 2.5.1

Reassignment changes a binding; it does not change the old object. If `str = "Goodbye"` follows `abc = str`, `str` refers to a different string while `abc` still refers to `"Hello"`. The same distinction applies beyond local variables, including instance and global variables. Constants can also be reassigned, but Ruby warns; modifying an object referenced by a constant is different and does not trigger that warning. section 2.5.2 section 3.7.2

>> a = [1,2,3]
=> [1, 2, 3]
>> b = a                   1
=> [1, 2, 3]
>> a.replace([4,5,6])
=> [4, 5, 6]
>> b                       2
=> [4, 5, 6]
>> a = [7,8,9]            3
=> [7, 8, 9]
>> b
=> [4, 5, 6]              4

Follow the two array variables through `replace` and then reassignment: changing the shared array is visible through both names, but rebinding `a` leaves `b` with the old array. section 9.2.3

Assignments also establish local variables within their scope. A local `x` inside one method does not change an `x` inside another; binding method arguments to parameters is another way local variables receive values. When Ruby parses a local assignment in a conditional body, it recognizes the variable even if the body never runs. In `if false; x = 1; end`, `x` therefore exists with the value `nil`. This parse-time rule helps Ruby distinguish bare local-variable names from method calls. section 2.5 section 6.1.2

Assignment can appear in a conditional test, such as `if m = /la/.match(name)`, where the assigned result is also tested. Take care with `=` before a literal: Ruby warns that `==` may have been intended. section 6.1.2

Assignment-looking syntax can also call a setter method. A setter commonly assigns its argument to an instance variable, as `@name = string` does. With syntax such as `session.year = year`, the expression evaluates to the right-hand side even if the underlying `year=` method returns something else. section 3.3 section 3.3.3

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Explains expression values, shared references, reassignment, scope, parse-time locals, and setter behavior, while stopping short of detailed object-storage internals.
Examples
Contrasts shared strings under `replace` and reassignment, and traces the same distinction through two variables referencing an array.
What it assumes
Assumes basic Ruby expressions and method calls while developing the distinction between variables and object references through examples.
What you can do after
Diagnose/debug with it when two variables unexpectedly reflect the same mutation or stop referring to the same object.
How it connects
Connects assignment to object references, mutation, method parameters, local-variable scope, conditional expressions, setter methods, and constants.

Also explained in

Compare how 7 books explain assignment →

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.