Ruby Standard Library has a Singleton module which implements the Singleton pattern. The first step in creating a Singleton class is to require and include the Singleton
module in a class:
require 'singleton'
class Logger
include Singleton
end
If you try to instantiate this class as you normally would a regular class, a NoMethodError
exception is raised. The constructor is made private to prevent other instances from being accidentally created:
Logger.new
#=> NoMethodError: private method `new' called for AppConfig:Class
To access the instance of this class, we need to use the instance()
:
first, second = Logger.instance, Logger.instance
first == second
#=> true
Logger example
require 'singleton'
class Logger
include Singleton
def initialize
@log = File.open("log.txt", "a")
end
def log(msg)
@log.puts(msg)
end
end
In order to use Logger
object:
Logger.instance.log('message 2')
Without Singleton include
The above singleton implementations can also be done without the inclusion of the Singleton module. This can be achieved with the following:
class Logger
def self.instance
@instance ||= new
end
end
which is a shorthand notation for the following:
class Logger
def self.instance
@instance = @instance || Logger.new
end
end
However, keep in mind that the Singleton module is tested and optimized, therefore being the better option to implement your singleton with.