Introduction
Every Ruby object carries a hidden, anonymous class called its singleton class (also known as the eigenclass or metaclass). This lesson explains what the singleton class is, how to access it, and why understanding it unlocks the secret behind class methods.
Key Concepts
- Singleton Class: A hidden class unique to a single object that holds methods defined only for that object.
- Eigenclass: An older synonym for singleton class, still found in many Ruby books.
- Class Methods: Methods defined on a class object, which are technically singleton methods on that class.
Real World Context
When you write User.find(1) in Rails, find is not an instance method — it is a singleton method on the User class object. Understanding the singleton class explains why class methods are inherited by subclasses and how frameworks like ActiveRecord build their query interfaces.
Deep Dive
The singleton class holds methods unique to a single object. You can add a method to one specific string without affecting any other string:
rubyobj = "hello" # Add method to this string only def obj.shout upcase + "!!!" end obj.shout # => "HELLO!!!" "world".shout # NoMethodError!
Only obj has the shout method. Other strings are unaffected because the method lives in the singleton class of that specific object.
There are two ways to access an object's singleton class:
rubyobj = Object.new # Method 1: singleton_class method obj.singleton_class # Method 2: class << syntax class << obj def exclusive_method "only for this object" end end
Both approaches give you access to the same hidden class. The class << obj syntax opens the singleton class body so you can define multiple methods at once.
Class methods are actually singleton methods on the class object. All three of the following definitions are equivalent:
rubyclass User # These are equivalent: def self.find(id) # ... end end # Same as: class << User def find(id) # ... end end # Same as: def User.find(id) # ... end
Each version adds the find method to User's singleton class. Because User is itself an object (an instance of Class), it can have singleton methods just like any other object.
Singleton classes also form their own inheritance chain, which is why class methods are inherited:
rubyclass Animal; end class Dog < Animal; end Dog.singleton_class.superclass == Animal.singleton_class # true!
Since Dog's singleton class inherits from Animal's singleton class, any class method defined on Animal is also available on Dog.
Common Pitfalls
- Confusing singleton methods with instance methods — Writing
def self.findinside a class body defines a class method (singleton method on the class), not an instance method. CallingUser.new.findwill raiseNoMethodError. - Forgetting that Integer (immediate values)/Symbol/true/false/nil cannot have singleton classes — Immediate values in Ruby share instances, so you cannot define singleton methods on them.
Best Practices
- Use
def self.method_namefor clarity — Althoughclass << selfworks,def self.method_namemakes it immediately obvious that you are defining a class method. - Check with
singleton_methods— Callobj.singleton_methodsto list all singleton methods on an object, which is helpful when debugging metaprogrammed code.
Summary
- Every Ruby object has a hidden singleton class that holds methods unique to that object.
- Class methods are singleton methods on the class object, which is why they are inherited by subclasses.
- You can access the singleton class with
obj.singleton_classor theclass << objsyntax.
Code Examples
class Animal
def self.kingdom
"Animalia"
end
end
class Dog < Animal; end
Dog.kingdom # => "Animalia"
Dog.singleton_class.superclass == Animal.singleton_class # => true