Question

Understanding `class << self` in Ruby

rubymetaclasseigenclasssingleton

Question

What does class << self do in Ruby?

I want to understand what this Ruby idiom means, how it works, and when it should be used. For example, what is happening in code like this?

class Example
  class << self
    def greet
      "hello"
    end
  end
end

How is this different from writing a class method in other Ruby styles?

Short Answer

By the end of this page, you will understand that class << self opens the singleton class of an object in Ruby. Inside that block, methods you define become methods on that specific object. When used inside a class body with self, it is a common way to define class methods. You will also see how it compares with def self.method_name, where it is useful in real code, and which beginner mistakes to avoid.

Concept

Ruby lets every object have its own private place to store methods that belong only to that object. That hidden place is called the singleton class (also called the eigenclass).

When you write:

class << self
  # methods here
end

you are opening the singleton class of whatever self currently refers to.

Why this matters

In Ruby, classes are also objects. That means a class object can have its own methods.

For example:

  • instance methods belong to instances of a class
  • class methods belong to the class object itself

So inside a class definition:

class User
  def name
    "instance name"
  end
end

name is an instance method. It is called on objects created from User.

But if you write:

class User
  def self.find
    "class method"
  end
end

then find belongs to the User object itself.

class << self is another way to define those class methods:

class User
  class << self
    def find
      "class method"
    end
  end
end

Both approaches create class methods here.

The key idea

  • self means “the current object”
  • class << obj opens the singleton class of obj
  • methods defined there belong only to that object

That means class << self does not always mean “define class methods.” It means “open the singleton class of the current object.” Inside a normal class body, the current object is the class itself, so the methods become class methods.

Why Ruby has this feature

It gives Ruby a flexible object model:

  • you can add methods to one object only
  • you can group several class methods together
  • you can change visibility for multiple class methods at once
  • metaprogramming features often rely on singleton classes

This concept appears often in Ruby frameworks and gems, especially in DSL-style code and library internals.

Mental Model

Think of every Ruby object as having:

  • a main toolbox shared by all objects of its class
  • a special personal toolbox just for itself

The singleton class is that personal toolbox.

If you open it with:

class << self
end

you are saying:

“Let me add methods to this object's personal toolbox.”

Now imagine a class like User.

User is itself an object. So User also has a personal toolbox. Methods added there become class methods.

  • methods in the regular class body -> used by instances like User.new
  • methods in the singleton class of User -> used by User itself

So the mental shortcut is:

  • regular class body = methods for future objects
  • class << self inside a class = methods for the class object now
Take Quiz

Syntax and Examples

Core syntax

Defining a class method with def self.method_name

class Product
  def self.count
    42
  end
end

puts Product.count

Defining the same thing with class << self

class Product
  class << self
    def count
      42
    end
  end
end

puts Product.count

Both print:

42

Example: multiple class methods

class << self becomes especially useful when you want to define several class methods together.

class Calculator
  class << self
    def add(a, b)
      a + b
    end

    def multiply(a, b)
      a * b
    end
  end
end

puts Calculator.add(2, 3)
puts Calculator.multiply(4, 5)

This is similar to writing:

class Calculator
  def self.add(a, b)
    a + b
  end

  def self.multiply(a, b)
    a * b
  end
end

Example: singleton methods on a single object

class << self is not limited to classes.

user = "Alice"

class << user
  def shout_name
    upcase
  end
end

puts user.shout_name

This adds shout_name only to that one string object.

Another string will not have that method:

other_user = "Bob"
# other_user.shout_name
# => NoMethodError

Example: setting visibility for class methods

class ApiClient
  class << self
    def fetch
      token
    end

    private

    def token
      "secret-token"
    end
  end
end

Here, fetch is a public class method and token is a private class method.

That is one reason developers like class << self: it can group methods and visibility rules neatly.

Step by Step Execution

Consider this code:

class Example
  class << self
    def greet
      "hello"
    end
  end
end

puts Example.greet

Step-by-step

1. Ruby starts defining the class

class Example

Ruby creates or reopens the Example class object.

Inside this class body, self is Example.

2. Ruby sees class << self

class << self

Since self is Example, this is the same idea as:

class << Example

Ruby opens the singleton class of the Example object.

3. Ruby defines greet

def greet
  "hello"
end

Because we are inside the singleton class of Example, greet becomes a method on Example itself.

4. The class definition ends

end
end

Now Example has a class method called greet.

5. The method is called

puts Example.greet

Ruby looks for a method named greet on the Example object, finds it in its singleton class, and returns:

hello

Quick trace of self

Inside the outer class body:

class Example
  puts self
end

Output:

Example

Inside the singleton class block:

class Example
  class << self
    puts self
  end
end

Now self refers to the singleton class object being opened, not the ordinary class body context. But the practical result is still that methods defined there become class methods of Example.

Real World Use Cases

1. Grouping class methods in models or service classes

class Report
  class << self
    def daily
      "daily report"
    end

    def weekly
      "weekly report"
    end
  end
end

This keeps related class-level behavior together.

2. Private helper methods for class methods

class SlugGenerator
  class << self
    def generate(text)
      normalize(text).downcase.gsub(" ", "-")
    end

    private

    def normalize(text)
      text.strip
    end
  end
end

This is useful when one class method needs helper methods that should not be public.

3. DSLs and framework internals

Ruby libraries often define behavior on classes themselves, not only on instances. For example:

  • configuration methods
  • registration methods
  • macros-like APIs

These may use singleton classes internally.

4. Attaching behavior to one object only

logger = Object.new

class << logger
  def info(message)
    puts "INFO: #{message}"
  end
end

logger.info("Started")

This pattern is less common in beginner code, but it shows the real meaning of singleton methods clearly.

5. Module-level utility methods

A module can also use class << self to define methods callable on the module itself.

module Formatter
  class << self
    def titleize(text)
      text.split.map(&:capitalize).join(" ")
    end
  end
end

puts Formatter.titleize("ruby singleton class")
Take Quiz

Real Codebase Usage

In real Ruby projects, developers use class << self in a few common patterns.

Grouping class methods

Instead of repeating self. many times:

class User
  def self.find(id)
    # ...
  end

  def self.active
    # ...
  end
end

they may group them:

class User
  class << self
    def find(id)
      # ...
    end

    def active
      # ...
    end
  end
end

This is mostly a style choice when visibility is not involved.

Using private class methods

This is one of the strongest practical reasons to use it.

class Invoice
  class << self
    def build_total(items)
      validate_items(items)
      items.sum { |item| item[:price] }
    end

    private

    def validate_items(items)
      raise ArgumentError, "items must be an array" unless items.is_a?(Array)
    end
  end
end

Guard clauses and validation

Class methods often act as entry points, so they commonly use:

  • argument validation
  • early returns
  • helper methods
  • error handling
class JsonLoader
  class << self
    def parse(text)
      return {} if text.nil? || text.empty?
      JSON.parse(text)
    rescue JSON::ParserError
      {}
    end
  end
end

Configuration APIs

Some classes expose class-level configuration:

class AppConfig
  class << self
    attr_accessor :api_key, :timeout
  end
end

AppConfig.api_key = "abc123"

This defines getter and setter methods on the class object.

Framework internals and metaprogramming

Ruby frameworks sometimes open singleton classes directly to:

  • define macros
  • override behavior for one object
  • add methods dynamically
  • manage inheritance hooks

Beginners do not need to master metaprogramming immediately, but understanding class << self makes those codebases easier to read.

Common Mistakes

1. Thinking it always means “class methods”

This is only true when self is a class object.

name = "Ruby"

class << name
  def excited
    upcase + "!"
  end
end

Here it adds a method to one string object, not to a class.

2. Confusing instance methods with class methods

Broken example:

class User
  def greet
    "hello"
  end
end

User.greet

This fails because greet is an instance method.

Fix:

class User
  def self.greet
    "hello"
  end
end

User.greet

Or:

class User
  class << self
    def greet
      "hello"
    end
  end
end

3. Overusing it for a single method

If you only need one class method, this is often simpler:

class User
  def self.find
    # ...
  end
end

Instead of:

class User
  class << self
    def find
      # ...
    end
  end
end

Both work, but the first is shorter.

4. Forgetting method visibility rules

Inside class << self, private affects methods defined after it.

class Demo
  class << self
    private

    def hidden
      "secret"
    end
  end
end

# Demo.hidden
# => NoMethodError

5. Assuming singleton methods are shared by all objects

Broken expectation:

a = "hello"
b = "world"

class << a
  def loud
    upcase
  end
end

puts a.loud   # works
# puts b.loud # fails

A singleton method belongs only to a.

6. Making code harder to read unnecessarily

class << self is useful, but if a simpler form is clearer, prefer the clearer one. Readability matters.

Comparisons

class << self vs def self.method_name

StyleBest forExampleNotes
def self.nameOne or two class methodsdef self.find; endShort and easy to read
class << selfGrouping many class methodsclass << self; def find; end; endUseful for shared visibility like private

Instance methods vs class methods

TypeDefined howCalled onExample call
Instance methoddef greetan instanceUser.new.greet
Class methoddef self.greet or inside class << selfthe class objectUser.greet

Singleton method on one object vs regular class method

ConceptBelongs toExample
Regular instance methodall instances of a classevery User.new can call it
Class methodthe class objectUser.find
Singleton methodone specific object onlyonly one string or one object can call it

When to choose which

  • Use def self.method_name for small, simple class APIs.
  • Use class << self when you want to:
    • define many class methods together
    • mark some class methods as private or protected
    • make the class-level structure easier to group
  • Use class << object when you intentionally want behavior on one object only.
Take Quiz

Cheat Sheet

Quick reference

Define a class method

class User
  def self.find
    "found"
  end
end

Same idea with class << self

class User
  class << self
    def find
      "found"
    end
  end
end

What class << self means

  • open the singleton class of self
  • define methods on the current object
  • inside a class body, that usually means class methods

Works on any object

obj = Object.new

class << obj
  def special
    "only for this object"
  end
end

Common use case

class Api
  class << self
    def call
      token
    end

    private

    def token
      "secret"
    end
  end
end

Rules to remember

  • classes are objects in Ruby
  • every object can have singleton methods
  • self depends on current context
  • class << self is often about grouping class methods
  • it is especially useful with private

Readability tip

  • one class method: prefer def self.name
  • several grouped class methods: consider class << self

FAQ

What is class << self in Ruby?

It opens the singleton class of the current object. Inside that block, methods become methods of that object.

Is class << self the same as defining class methods?

Not exactly. It defines methods on the current object. Inside a class body, the current object is the class, so the result is class methods.

Is class << self the same as def self.method_name?

For defining class methods inside a class, they often produce the same result. class << self is more useful when grouping several methods or setting visibility.

Why would I use class << self instead of def self.method_name?

Use it when you want to define multiple class methods together or make some of them private.

Can I use class << self outside a class?

Yes. You can use class << object on any object to define methods only for that object.

What is a singleton class in Ruby?

It is a hidden class attached to one object. It stores methods that belong only to that object.

Does class << self create instance methods?

No. It creates methods on the current object's singleton class, not regular instance methods for all instances.

Is class << self common in Rails or Ruby gems?

Yes. You will often see it in Ruby libraries, Rails code, DSLs, and framework internals.

Take Quiz

Mini Project

Description

Build a small Ruby utility class that converts text in different ways using class methods. This project demonstrates why class << self is useful for grouping multiple class methods and for keeping helper methods private.

Goal

Create a TextTools class with public class methods for formatting strings and a private class helper method used internally.

Requirements

  • Create a class named TextTools.
  • Use class << self to define at least two public class methods.
  • Add one private class helper method inside the same block.
  • One method should title-case a string.
  • Another method should create a URL-friendly slug from a string.
Take Quiz

Keep learning

Related questions

View more