Variables, Constants and Scope

4.1 Variable Types

name = "Ana"            # local variable
@age = 30               # instance variable (belongs to an object)
@@count = 0             # class variable (shared by a class and its subclasses; use sparingly)
$debug = true           # global variable (avoid)
PI = 3.14159            # constant (reassignment gives a warning, not an error)

4.2 Multiple and Parallel Assignment

a, b, c = 1, 2, 3
a, b = b, a                     # swap
first, *rest = [1, 2, 3, 4]     # first = 1, rest = [2, 3, 4]
*init, last = [1, 2, 3]
x = y = 0                       # chained assignment
head, (inner_a, inner_b) = [1, [2, 3]]   # nested destructuring
count ||= 0                     # assign if nil/false (memoization idiom)
total += 5                      # also -=, *=, /=, **=, %=, <<= ...

4.3 Scope Rules

def, class, and module create new scopes (scope gates). Local variables don't leak in.

Blocks create a new scope but can see outer local variables (closures).

Block-local variables: [1, 2].each { |n; x| x = n } (the ; x declares a block-local variable).

x = 10
[1, 2].each { |n| x += n }     # block sees x
puts x                         # 13

def method_scope
  # x is NOT visible here
  defined?(x)                  # nil
end

4.4 Constants

Constants are looked up lexically, then through the inheritance chain. Access nested ones with :: (Math::PI, MyModule::VERSION).

freeze makes objects immutable: COLORS = %w[red green].freeze.

4.5 Introspection

defined?(foo)            # nil, "local-variable", "method", "expression"...
local_variables
instance_variables
self                     # the current object (main at top level)
binding.local_variable_get(:x)