The Singleton pattern ensures that only one instance of a class exists in a program and provides a global access point to that instance. In Ruby, the Singleton module is available in the singleton library, making it easy to implement.
Using the Singleton Module
Ruby provides a built-in Singleton module that ensures only one instance of a class is created.
Example: Implementing Singleton Class
require 'singleton'
class Logger
include Singleton
def log(message)
puts "[LOG]: #{message}"
end
end
# Getting the single instance
logger1 = Logger.instance
logger2 = Logger.instance
logger1.log("Application started")
# Checking if both instances are the same
puts logger1.object_id == logger2.object_id # true
Explanation:
include Singletonensures that only one instance ofLoggercan be created..instancemethod provides the singleton instance.- Direct instantiation is prevented (
Logger.newwill raise an error).
Creating a Singleton Without the Singleton Module
If you prefer not to use the Singleton module, you can manually implement the Singleton pattern.
Example: Manual Singleton Implementation
class Configuration
@instance = nil
private_class_method :new # Prevents direct instantiation
def self.instance
@instance ||= new
end
def setting
"Dark Mode Enabled"
end
end
# Getting the singleton instance
config1 = Configuration.instance
config2 = Configuration.instance
puts config1.setting # "Dark Mode Enabled"
puts config1.object_id == config2.object_id # true
How It Works:
@instance ||= newensures that only one instance is created.private_class_method :newprevents direct instantiation.- Only
Configuration.instancecan access the instance.
When to Use Singleton in Ruby?
Use a Singleton when: ✅ You need a single shared resource (e.g., configuration, logging, database connection).
✅ You want to control access to an object, ensuring only one instance exists.
✅ You need global access to an instance without passing it around manually.
Common Use Cases
- Logger Service
- Application Configuration
- Cache Storage
- Database Connection Management
Singleton vs. Global Variables
| Feature | Singleton Pattern | Global Variable ($var) |
|---|---|---|
| Encapsulation | Yes (Encapsulated in class) | No (Accessible everywhere) |
| Control Over Instantiation | Yes (Only one instance allowed) | No (Can be reassigned anytime) |
| Thread Safety | Safer with Singleton Module | Risky (Mutable state) |
Using a Singleton is generally safer than using global variables, as it provides better encapsulation and prevents accidental modifications.
Thread-Safe Singleton
The built-in Singleton module ensures thread safety in Ruby. However, if implementing manually, you need to make it thread-safe.
Example: Thread-Safe Singleton
require 'thread'
class SafeSingleton
@instance = nil
@mutex = Mutex.new
private_class_method :new
def self.instance
@mutex.synchronize do
@instance ||= new
end
end
end
How It Works:
@mutex.synchronizeensures that only one thread initializes the instance.- This prevents race conditions in multi-threaded applications.
Singleton with Lazy Initialization
In some cases, you might want to initialize the singleton only when needed.
Example: Lazy Singleton
class LazyLoader
@instance = nil
def self.instance
@instance ||= new
end
def load_data
puts "Loading data..."
end
end
# Instance is created only when first used
loader = LazyLoader.instance
loader.load_data
Why Use Lazy Initialization?
- Saves memory by not creating the instance until needed.
- Useful for performance optimization in applications.
Database Connection Pooling
Most web frameworks, like Ruby on Rails, Django, or Spring Boot, use the Singleton pattern for managing database connections.
How It Works:
- A single instance of a connection pool is created and shared across the application.
- The connection pool is responsible for managing database connections, ensuring they are reused rather than recreated, which reduces overhead.
- Ruby on Rails uses the
ActiveRecord::Base.connectionsingleton to manage and provide database connections.
# Example in Rails
ActiveRecord::Base.connection.execute("SELECT * FROM users")
- The
ActiveRecord::Base.connectionis a Singleton, ensuring all parts of the application share the same connection object for efficiency.


