Variables
Ruby variables: local, instance, class, global, constants. Sigils signal scope; assignment is just labelling.
Ruby — variables
EXAMPLE
# ===== Local variables (lowercase or _) =====
total = 0
_skip = nil # leading _ marks 'intentionally unused' to linters
# Locals live in the smallest scope:
def add(a, b)
result = a + b # local to add
result
end
# ===== Instance variables (@name) =====
class User
def initialize(name, email)
@name = name
@email = email
end
def display
"#{@name} <#{@email}>"
end
end
# Reading an unset @var returns nil (no error). Linters warn.
# ===== Class variables (@@count) — used rarely; subclasses share them =====
class Counter
@@count = 0
def self.bump
@@count += 1
end
def self.value
@@count
end
end
Counter.bump; Counter.bump
Counter.value # => 2
# Modern Ruby usually uses class-level @vars via class << self instead:
class Counter2
class << self
attr_accessor :count
end
self.count = 0
end
Counter2.count += 1
# ===== Global variables ($global) =====
# Avoid. Stdin/stdout aside ($stdin, $stdout, $stderr), globals are a code smell.
$debug = false
# ===== Constants (Title-cased) =====
MAX_RETRIES = 3
class Money
CURRENCY = 'AUD'
end
Money::CURRENCY # 'AUD'
# Constants are 'constant' by convention; Ruby will WARN on reassignment, not error.
# ===== Multiple assignment =====
a, b = 1, 2
a, b = b, a # swap
first, *rest = [10, 20, 30] # first=10, rest=[20, 30]
*init, last = [1, 2, 3] # init=[1, 2], last=3
# Destructuring in block args:
{a: 1, b: 2}.each { |k, v| puts "#{k}=#{v}" }
# ===== Symbol vs string =====
:status # immutable, interned symbol; great as a hash key
'status' # mutable string
# Prefer symbols for keys and identifiers; strings for human-facing text.
# ===== nil and false =====
# Only nil and false are falsy. 0, '', [], {} are all truthy.
# ===== Type checks (use sparingly) =====
1.is_a?(Integer) # true
1.is_a?(Numeric) # true
'x'.respond_to?(:upcase) # true
# ===== Coercion =====
'42'.to_i # 42
'42abc'.to_i # 42 (lenient — bites you on validation)
Integer('42') # 42 — strict, raises on bad input
Integer('42abc') # ArgumentError
# ===== Freezing (immutability where it matters) =====
NAME = 'hello'.freeze
NAME << '!' # FrozenError
# Ruby 3+ frozen string literals (per-file pragma):
# frozen_string_literal: true
# ===== Patterns to internalise =====
# - Default to local variables; only escalate to @, @@, $ when you must
# - Use symbols for keys, strings for text
# - Multiple assignment and splat (* / **) read beautifully — use them
# - Use Integer(x) when validation matters; .to_i is lenient
# - Freeze constants and configuration strings to catch surprise mutations
# ===== Pitfalls =====
# - @typo silently returns nil instead of raising -> use linters or :@typo helpers
# - Class variables and inheritance get weird; reach for class-level instance vars
# - '0' is truthy, 'false' is truthy — only nil/false are falsy
# - Reassigning constants warns instead of erroring -> easy to miss
# - .to_i on a string with leading whitespace works; on '12px' returns 12 (silent truncation)
Why it matters
Ruby variables live in scopes signalled by their first character. Default to locals, lean on symbols for identifiers, use freeze where immutability earns its keep. The sigil system is opinionated and the language rewards reading the @, @@, $ as a small contract.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
name = 'Ada' # local @age = 36 # instance @@count = 0 # class $global = nil # globalTry it Yourself »
Discussion
Loading…