self & Class Methods
Ruby self: who am I? Instance vs class context, defining class methods, and the subtle rules around self.
Ruby — self
EXAMPLE
# ===== In an instance method =====
class User
attr_accessor :name
def initialize(name)
@name = name
end
def greet
# self refers to the current instance
"Hi from #{self.name}" # or just 'name' since attr_accessor exposes it
end
end
User.new('Alex').greet # 'Hi from Alex'
# ===== self= setter requires explicit self ===== =====
class User
attr_accessor :name
def rename(new_name)
self.name = new_name # self. is REQUIRED for the setter
# name = new_name # creates a LOCAL variable, doesn't call name=
end
end
# ===== Class-level: self IS the class =====
class User
puts self # User
def self.create(name)
new(name) # equivalent to User.new(name)
end
end
User.create('Alex')
# ===== Defining class methods =====
# Three styles:
# 1. def self.method
class Service
def self.start; end
end
# 2. class << self ... end (singleton class)
class Service
class << self
def start; end
def stop; end
end
end
# 3. Module#module_function (works for modules being mixed in)
# ===== Inside class << self =====
class Service
class << self
attr_accessor :registry
end
end
Service.registry = {}
# ===== self vs nil =====
# self is never nil inside a method body.
# But in main scope, self is the 'main' object:
puts self # main
# ===== Why does it matter =====
# 1. Distinguishing instance methods (def x) from class methods (def self.x)
# 2. Using setters requires explicit self.
# 3. Block context: self inside a block is usually the enclosing self,
# UNLESS instance_exec changes it.
# ===== Block context manipulation =====
class Config
def self.configure(&block)
instance_eval(&block) # 'self' inside block becomes the Config class
end
end
Config.configure do
puts self # Config
end
# Rake / DSL style libraries lean on this.
# ===== Singleton methods (per-object) =====
str = 'hello'
def str.shout
upcase + '!'
end
str.shout # 'HELLO!'
# But 'world'.shout would error — singleton method only on this object.
# ===== Patterns to internalise =====
# - def self.method for class methods
# - self.attr = ... when calling a setter
# - instance_eval / instance_exec for DSL contexts
# - Avoid singleton methods on objects from outside; surprising for readers
# ===== Pitfalls =====
# - 'name = value' inside an instance method creates a LOCAL variable, not calling name=
# - Confusing class scope (where self is the class) with instance scope
# - Defining 'def method' inside class << self vs def self.method (both work; pick one for the team)
# - Forgetting that 'self' inside a Proc/Lambda is the enclosing context, not the method's receiver
Why it matters
self is who-am-I at this point. In instance methods, it is the instance. In class scope, it is the class. Setters always need explicit self. — local variables silently shadow them otherwise. DSLs lean on instance_eval to change self deliberately; for everyday code, the explicit forms are clearest.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
class Counter
def self.create = new(0) # class method
def initialize(start) = @n = start
end
Try it Yourself »
Discussion
Loading…