Created
August 2, 2013 07:44
-
-
Save mssola/6138155 to your computer and use it in GitHub Desktop.
Different ways to create the Singleton pattern in Ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# This files shows some possible implementations of the Singleton pattern | |
# in Ruby. I'm not a huge fan of the Singleton pattern, but it's nice | |
# in some cases. In this file I'm going to implement a simple logger. | |
# | |
## | |
# The first implementation that can come to our minds is to create a class | |
# that holds an instance as a class variable that can be accessed through | |
# the instance method called 'instance'. Then, with this instance you can | |
# log as usual. Furthermore, the 'new' class method is kept private to prevent | |
# the programmer of instantiating new logs. | |
class Log | |
def initialize | |
@log = File.new 'log.txt', 'a' | |
end | |
def log(msg) | |
@log.puts msg | |
end | |
@@instance = Log.new | |
def instance | |
@@instance | |
end | |
private_class_method :new | |
end | |
## | |
# We can also achieve the above implementation by including the | |
# Singleton module. | |
require 'singleton' | |
class IncludedSingletonLog | |
include Singleton | |
def initialize | |
@log = File.new 'log.txt', 'a' | |
end | |
def log(msg) | |
@log.puts msg | |
end | |
end | |
## | |
# And here is a more basic implementation. Here I want to show the idea of | |
# eager instantiation (which also applies to the techniques used above). | |
# Eager instantiation means that the instance is created when the class gets | |
# loaded, even if it's not used. | |
class EagerLog | |
@@log = File.new 'log.txt', 'a' | |
def self.log(msg) | |
@@log.puts msg | |
end | |
private_class_method :new | |
end | |
## | |
# On the other hand, lazy instantiation means that the instance is created | |
# only when the programmer wants to use this class for the first time. | |
class LazyLog | |
def self.log | |
@@log ||= File.new 'log.txt', 'a' | |
@@log.puts msg | |
end | |
private_class_method :new | |
end | |
## | |
# In Ruby, the difference between a Module and a Class is just three methods: | |
# :new, :allocate and :superclass. So a Module is almost the same as a Class | |
# but it cannot be instantiated. Cool, we now can implement the above classes | |
# as modules but without calling the private_class_method method. | |
module ModuleLog | |
@@log = File.new 'log.txt', 'a' | |
def self.log(msg) | |
@@log.puts msg | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Method
instance
should be static =>def self.instance