When I need a singleton class in my Ruby code (for example, single logger for multiple classes) I usually use code like this:
class Parent_Singleton
@singleton = nil
def self.new
@singleton || (@singleton = super)
end
end
This approach allows me to avoid using the module Singleton
(because I don't want to use a special method instance
to get an object of this class, I just want to use the usual Parent_Singleton.new
in any part of my code to get my singleton object).
Another advantage of this approach is the ability to avoid using class variables @@singleton
which of course is a bad practice because of its behavior in inheritance. My code doesn't have this issue:
class Child_Singleton < Parent_Singleton
end
p1 = Parent_Singleton.new
p2 = Parent_Singleton.new
c1 = Child_Singleton.new
c2 = Child_Singleton.new
p1 == p2 # => true
c1 == c2 # => true
p1 == c1 # => false
p2 == c2 # => false
If I need to store some variable data in my class, it's also not a problem:
class Parent_Class
@singleton = nil
@some_data = ''
class << self
def new
@singleton || (@singleton = super)
end
def some_data
@some_data
end
def some_data=(value)
@some_data = value
end
end
end
class First_Child_Class < Parent_Class
end
class Second_Child_Class < Parent_Class
end
Parent_Class.some_data = 'Parent'
First_Child_Class.some_data = 'First_Child'
Second_Child_Class.some_data = 'Second_Child'
puts Parent_Class.some_data # => Parent
puts First_Child_Class.some_data # => First_Child
puts Second_Child_Class.some_data # => Second_Child
So my question is: if this code is bad, what's wrong with it? If this code is good, why the most of the examples worldwide suggest using either Singleton
module (with instance
method) or class variable-based singleton classes instead?