Recap: the one line you've already seen
Where this started
The lesson "The AND operator", in Logic: boolean algebra, taught && and its short-circuit behavior with this example:
current_user && current_user.subscription && current_user.subscription.active?
Right below it, that lesson showed one more line, labeled the "modern Ruby alternative", and moved on without explaining it:
current_user&.subscription&.active?
That was all &. got there: one line, one label, no mechanics. This course opens that line up.
What the && chain does
current_user && current_user.subscription && current_user.subscription.active? evaluates current_user three times and calls .subscription twice. A class that counts its own calls shows it:
a = Chain.new
a && a.b && a.b.c
a.calls
# 2 — .b ran twice
Each && clause starts again from the beginning of its expression. By the third clause Ruby doesn't remember that a.b was already computed; it runs a.b again as part of evaluating a.b.c.
What the &. chain does
a2 = Chain.new
a2&.b&.c
a2.calls
# 1 — .b ran exactly once
&. passes one value along the chain instead of starting over. It evaluates a2 once, calls .b on it, and hands that result to the next &., which calls .c on it. That's one evaluation per link, not one per clause.
The real behavior: the whole chain short-circuits
What "The AND operator" never showed is what happens when the nil could be anywhere along a longer chain. Take four User objects, each missing something at a different depth:
full.subscription.plan.name # "Pro" — user has a subscription with a plan
no_plan.subscription.plan&.name # subscription exists, plan doesn't
no_sub.subscription # user exists, subscription doesn't
nothing # the user itself is nil
Running user&.subscription&.plan&.name on all four:
full&.subscription&.plan&.name # "Pro"
no_plan&.subscription&.plan&.name # nil
no_sub&.subscription&.plan&.name # nil
nothing&.subscription&.plan&.name # nil
Every failure point gives the same outcome for the whole expression: nil, with no exception. That holds for the first link (nothing) and the last (no_plan, whose plan is nil). The mechanism: each &. only asks "is this receiver nil?" If so, it stops and returns nil at once, calling nothing and ignoring what comes after it. That nil becomes the receiver of the next &., which asks the same question, gets "yes" and stops too. The nil passes from link to link to the end, so a chain of any length collapses to nil as soon as one link fails.
Key takeaways
- "The AND operator" showed
current_user&.subscription&.active?as the "modern Ruby alternative" to an&&chain, with no explanation; this course starts there. - An
&&chain evaluates the receiver again at every clause, calling a shared method twice where the&.chain calls it once. &.passes one evaluated value along the chain instead of starting over; each link calls its method on the previous link's result.- With a
nilplanted at every depth,obj&.a&.b&.creturnsnilfor the whole expression as soon as any link isnil, first or last, and raises no exception.
Keep going with lesson 2
Safe navigation with arguments and blocks
Shows that &. passes arguments and blocks through unchanged and also works in front of operator methods like >.
A free account also gives you the quizzes, your progress and notes, and the discussion.