Skip to main content
โšก Calmops

Singleton Methods and the Singleton Class in Ruby

Introduction

A singleton method is a method defined on a specific object rather than on its class. Only that one object has the method โ€” no other instances of the same class do. This is one of Ruby’s most distinctive features and the foundation of how class methods work.

Defining Singleton Methods

Direct Definition

obj = Object.new

def obj.talk
  "Hi from singleton method!"
end

obj.talk          # => "Hi from singleton method!"
Object.new.talk   # => NoMethodError โ€” other objects don't have it

Using instance_eval

instance_eval changes self to the receiver, allowing you to define singleton methods inside a block:

s1 = "hello"
s2 = "world"

s1.instance_eval do
  def shout
    upcase + "!!!"
  end
end

s1.shout  # => "HELLO!!!"
s2.shout  # => NoMethodError โ€” s2 doesn't have this method

Using define_singleton_method

dog = Object.new
name = "Rex"

dog.define_singleton_method(:speak) do
  "#{name} says: Woof!"
end

dog.speak  # => "Rex says: Woof!"

Class Methods Are Singleton Methods

Here’s the key insight: class methods are singleton methods defined on the class object.

Since every class in Ruby is an object (an instance of Class), you can define singleton methods on it โ€” and those become class methods:

class People
  # This is a singleton method on the People class object
  def self.kind
    "human"
  end
end

# Equivalent ways to define the same method:
def People.kind
  "human"
end

People.singleton_class.define_method(:kind) { "human" }

All three define the same singleton method on the People class object.

Class Methods Are Inherited

Singleton methods on classes are inherited by subclasses:

class People
  def self.kind
    "human"
  end
end

class Student < People
end

puts People.kind   # => "human"
puts Student.kind  # => "human"  (inherited!)

This works because Ruby’s method lookup for class methods walks the singleton class hierarchy, which mirrors the regular class hierarchy.

The Singleton Class

Every Ruby object has a hidden singleton class (also called eigenclass or metaclass) that stores its singleton methods. You can open it with class << obj:

obj = Object.new

class << obj
  def greet
    "Hello from singleton class!"
  end

  def farewell
    "Goodbye!"
  end
end

obj.greet    # => "Hello from singleton class!"
obj.farewell # => "Goodbye!"

For a class, class << self opens the class’s singleton class โ€” this is where class methods live:

class Config
  class << self
    def default_timeout
      30
    end

    def default_retries
      3
    end

    attr_accessor :debug_mode
  end
end

Config.default_timeout  # => 30
Config.debug_mode = true
puts Config.debug_mode  # => true

Inspecting Singleton Methods

class Dog
  def self.species
    "Canis lupus familiaris"
  end
end

rex = Dog.new
def rex.fetch(item)
  "#{item} fetched!"
end

# Singleton methods on an instance
puts rex.singleton_methods.inspect
# => [:fetch]

# Singleton methods on a class (= class methods)
puts Dog.singleton_methods(false).inspect
# => [:species]

# Check if an object has a singleton class
puts rex.singleton_class
# => #<Class:#<Dog:0x...>>

puts Dog.singleton_class
# => #<Class:Dog>

Every Object Has Two Classes

Every Ruby object belongs to two classes:

  1. Its regular class โ€” shared with all instances
  2. Its singleton class โ€” unique to that object
dog = Dog.new

# Regular class (shared)
dog.class              # => Dog
dog.is_a?(Dog)         # => true

# Singleton class (unique to this object)
dog.singleton_class    # => #<Class:#<Dog:0x...>>

# Method lookup order
dog.singleton_class.ancestors
# => [#<Class:#<Dog:0x...>>, Dog, Object, Kernel, BasicObject]

When you call a method on dog, Ruby first looks in dog’s singleton class, then in Dog, then up the ancestor chain.

Practical Use Cases

Per-Object Behavior

class Logger
  def log(msg)
    puts "[DEFAULT] #{msg}"
  end
end

production_logger = Logger.new
staging_logger    = Logger.new

# Override log behavior only for production
production_logger.define_singleton_method(:log) do |msg|
  puts "[PROD #{Time.now}] #{msg}"
  # also send to external service
end

production_logger.log("Server started")  # => [PROD 2026-03-30 ...] Server started
staging_logger.log("Server started")     # => [DEFAULT] Server started

Mocking in Tests

Singleton methods are commonly used in tests to mock specific objects:

# In a test
payment_gateway = PaymentGateway.new

# Override just this instance's charge method
def payment_gateway.charge(amount)
  { success: true, transaction_id: "test-123" }
end

result = payment_gateway.charge(100)
puts result[:success]  # => true

DSL Configuration Objects

class AppConfig
  def self.configure
    config = new
    yield config
    config
  end

  def method_missing(name, *args)
    if name.to_s.end_with?('=')
      define_singleton_method(name.to_s.chomp('=')) { args.first }
    else
      super
    end
  end
end

config = AppConfig.configure do |c|
  c.database_url = "postgres://localhost/myapp"
  c.redis_url    = "redis://localhost:6379"
  c.debug        = true
end

puts config.database_url  # => "postgres://localhost/myapp"
puts config.debug         # => true

Singleton Class Hierarchy

The singleton class hierarchy mirrors the regular class hierarchy:

Regular classes:    Student < People < Object
Singleton classes:  #<Class:Student> < #<Class:People> < #<Class:Object>

This is why class methods are inherited โ€” Student’s singleton class inherits from People’s singleton class.

class People
  def self.kind; "human"; end
end

class Student < People; end

# Student's singleton class inherits from People's singleton class
puts Student.singleton_class.superclass
# => #<Class:People>

puts Student.singleton_class.ancestors.inspect
# => [#<Class:Student>, #<Class:People>, #<Class:Object>, ...]

Summary

Concept Description
Singleton method Method defined on a specific object, not its class
Singleton class Hidden class that stores an object’s singleton methods
Class method Singleton method on a class object
class << obj Opens the singleton class of obj
class << self Opens the current class’s singleton class (inside a class body)
obj.singleton_methods Lists singleton methods on obj
obj.singleton_class Returns the singleton class of obj

Resources

Comments