Suppose a method assigns `x = "Hello"` and calls another method that assigns `x = "Goodbye"`. When the first method resumes, its `x` is still `"Hello"`. The names match, but each method call has its own local variables. Scope is the reach or visibility of an identifier: knowing the current scope tells you which variable or constant a name can denote. section 2.5 section 5.2
The boundary depends on the kind of identifier:
- Local variables belong to a local scope. The top level and each `class`, `module`, or `def` definition start separate local scopes; each method call gets a fresh set of locals. section 5.2.2
- Ordinary global variables, marked with `$`, remain available across those boundaries. Instance variables instead belong to the object that is `self`; they are self-bound rather than scope-bound. section 5.2.1 section 5.2
- Constants depend on their enclosing classes or modules. A qualified path such as `M::C::X` identifies one explicitly; a leading `::` starts lookup at the top level. section 5.2.4
class C
a = 1 1
def local_a
a = 2 2
puts a
end
puts a 3
end
c = C.new
c.local_a 4
The `a` assigned in the class body prints as `1`. The `a` assigned inside `local_a` prints as `2`: entering `def` created a different local scope, even though the two assignments sit close together. section 5.2.2
Scope is not the same as `self`. Scope governs visibility; `self` is the current object. A recursive method call can keep the same `self` while receiving fresh local variables, leaving the earlier call’s values intact. section 5.2 section 5.2.3
Blocks add a useful contrast. A block can read and reassign a local that already exists outside it, so the outer value can change. But a block parameter with the same name is a different variable: assigning to that parameter does not reassign the outer local. This behavior also matters when blocks become closures. section 6.3.8
An assignment that never runs
After `if false; x = 1; end`, inspecting `x` yields `nil`, while inspecting an otherwise unknown `y` raises an error. Ruby’s parser recognized `x = 1` and allocated a local even though the conditional body did not execute. Because bare words can also be method calls, this parse-time distinction matters when a name appears to be missing. section 6.1.2 section 2.5.4
When a name resolves unexpectedly, first locate the enclosing definitions and check whether it is a block parameter. Then distinguish locals from globals, constants, and variables belonging to `self`. `local_variables` lists currently defined local names, while `rdbg` can display locals and their values at a breakpoint. section 15.3.1 section 1.4.5




















