Is it possible, that singleton.rb should be avoided, if we look at following facts:
Singleton means there is only one Object.
With singleton.rb there are two objects, once the object and again an object of , which can be accessed with .instance.
In GOF, there are listed 5 consequences of using the pattern:
- controlled access to sole instance
- reduced name space
- permits refinement of operations and representation
- permits a variable number of instances
- more flexible than class operations
1.-3. are the same with and without singleton.rb . 4. and 5. means, sometimes you decide to change from singleton to factory controlling the instance count.
So, if I want to change, I remove class << self and add a factory method to the class.
The main difference is the initialization of the Class object. Therefore, there have to be a pattern for only initializing once, like undefing the init method after calling it, which permits also an easy change to factory pattern. Also it have to be clear, when the initialization takes place, which is a bit strange with Singleton#instance, I find.
Do i make some serious error in reasoning ? Is singleton.rb useful anymore, if we have an advanced class initialization scheme ?
-- Matthias Georgi
Simon: I'm not sure that all patterns need to go into the Pattern namespace, but it's a good collection. From a usage perspective, though, it would be possible to "include Pattern" and have access to Pattern::Iterator::Collection as if it were still Iterator::Collection. If we use the Pattern namespace, then it definitely should go in lib/patttern/singleton.rb, as an example.
Matthias: I'm not sure that I understand what you're saying here. From a practical perspective, there is only a single instance with the use of Singleton (singleton.rb). The module Singleton provided by singleton.rb simplifies the implementation of making a GOF Singleton pattern object. Using Singleton, you simply do:
class MySingletonObject
include Singleton
end
MySingletonObject.new is made private and a new method MySingletonObject.instance is provided. As I understand it, there is the Multion pattern that should be as simple to implement (e.g., "include Multiton"). There is no removing "class << self" involved. I think that singleton.rb is still useful, but it needs to either be renamed or put into a different namespace. -- Austin
Well, what I meant, was
class MySingletonObject
singleton_class do
def initialize
end
end
initialize
end
As you see, this is simpler and does nearly the same.
It doesn't do the same at all, presuming that singleton_class does much the same as class << self; self; end. The Singleton module does, more or less:
class MySingletonObject
class << self
private :new
def instance
...
end
end
end
It has been a while since I've used singleton.rb, but it is not related to class << self (the singleton class object for the class of MySingletonObject). Quite honestly, I'm not seeing where you're going because of this. It is easier to tell people that they can make an object have one and only one instance by doing "require 'singleton'; include Singleton" in their class definition. -- Austin Ziegler
I just wanted to point out that the singleton pattern exists inherently in the singleton class itself, which can be used _without_ creating an instance. -- Matthias Georgi
Matthias, if you run your code with this added:
m = MySingletonObject.new
p m
m = MySingletonObject.new
p m
(and with your block version of singleton_class) you'll see that you're not actually doing the equivalent of Singleton. You can create two different instances of MySingletonObject.
I'm not sure whether there's a way to implement Singleton using singleton classes. I don't think it's necessarily important, though, especially if it's only done to make sense in retrospect of the coincidence of names. I think it's better to break the names out, as Austin suggests.
I am voting yay for the Pattern::Singleton and pattern/singleton.rb modification. Beyond the points made by Austin, it follows the scheme of keeping the root dir of lib/ relatively clean . As far as removing singleton completely, I think too many people use it for it to be removed, but it is worth getting more opinions about it. -- Zachary P. Landau
I was reading through my major backlog of ruby-talk archives and I found that points out that a proper singleton (ensuring only one instance of a class) could be used to control access to a database that doesn't do concurrency very well.
Also, to the anonymous poster before Zachary, thank you for saying what I was finding difficult to say. The Singleton Pattern is intended to restrict instance creation; the separate MySingletonObjects would actually have separate singleton classes. While the pattern could be generalised to a Pool of objects (with count 1), I think the case of one object and only one object is common enough to warrant Singleton. -- Austin Ziegler
I admit, I left something out, I just wanted to give a hint. To show a working example:
module Kernel
def singleton(&block)
s = class << self; self; end
s.class_eval(&block)
s.class_eval do
private :new, :allocate
def instance; self; end
end
initialize
end
end
class MySingleton
singleton do
def initialize
..
end
def hello
end
...
end
end
MySingleton.instance.hello
MySingleton.hello
-- Matthias Georgi
IMO if Singleton is to be put into a module/namespace, it should be Antipattern::Singleton, not Pattern::Singleton. Blind use of the singleton pattern makes for code that is difficult to unit test, and I think unit tests are something the Ruby community would like to keep as one of its defining characteristics.
I also think that renaming singleton.rb or moving Singleton to a module solely to reduce confusion with the singleton class is a bad idea (since it will break existing code). Newcomers to Ruby come in with an idea of what "singleton" means already and so they will be confused when they see "singleton class" if it is not explained to them. It would be better to either clearly address this in a FAQ somewhere (explaining the difference between the two and why singleton class is a singleton of its own right), or start a movement to start writing metaclass instead of singleton class.
-- Paul Brannan
Is it possible, that singleton.rb should be avoided, if we look at following facts:
Singleton means there is only one Object.
With singleton.rb there are two objects, once the object and again an object of , which can be accessed with .instance.
In GOF, there are listed 5 consequences of using the pattern:
1.-3. are the same with and without singleton.rb . 4. and 5. means, sometimes you decide to change from singleton to factory controlling the instance count.
So, if I want to change, I remove class << self and add a factory method to the class.
The main difference is the initialization of the Class object. Therefore, there have to be a pattern for only initializing once, like undefing the init method after calling it, which permits also an easy change to factory pattern. Also it have to be clear, when the initialization takes place, which is a bit strange with Singleton#instance, I find.
Do i make some serious error in reasoning ? Is singleton.rb useful anymore, if we have an advanced class initialization scheme ?
-- Matthias Georgi
Simon: I'm not sure that all patterns need to go into the Pattern namespace, but it's a good collection. From a usage perspective, though, it would be possible to "include Pattern" and have access to Pattern::Iterator::Collection as if it were still Iterator::Collection. If we use the Pattern namespace, then it definitely should go in lib/patttern/singleton.rb, as an example.
Matthias: I'm not sure that I understand what you're saying here. From a practical perspective, there is only a single instance with the use of Singleton (singleton.rb). The module Singleton provided by singleton.rb simplifies the implementation of making a GOF Singleton pattern object. Using Singleton, you simply do:
MySingletonObject.new is made private and a new method MySingletonObject.instance is provided. As I understand it, there is the Multion pattern that should be as simple to implement (e.g., "include Multiton"). There is no removing "class << self" involved. I think that singleton.rb is still useful, but it needs to either be renamed or put into a different namespace. -- Austin
Well, what I meant, was
As you see, this is simpler and does nearly the same.
It doesn't do the same at all, presuming that singleton_class does much the same as class << self; self; end. The Singleton module does, more or less:
It has been a while since I've used singleton.rb, but it is not related to class << self (the singleton class object for the class of MySingletonObject). Quite honestly, I'm not seeing where you're going because of this. It is easier to tell people that they can make an object have one and only one instance by doing "require 'singleton'; include Singleton" in their class definition. -- Austin Ziegler
I just wanted to point out that the singleton pattern exists inherently in the singleton class itself, which can be used _without_ creating an instance. -- Matthias Georgi
Matthias, if you run your code with this added:
(and with your block version of singleton_class) you'll see that you're not actually doing the equivalent of Singleton. You can create two different instances of MySingletonObject.
I'm not sure whether there's a way to implement Singleton using singleton classes. I don't think it's necessarily important, though, especially if it's only done to make sense in retrospect of the coincidence of names. I think it's better to break the names out, as Austin suggests.
I am voting yay for the Pattern::Singleton and pattern/singleton.rb modification. Beyond the points made by Austin, it follows the scheme of keeping the root dir of lib/ relatively clean . As far as removing singleton completely, I think too many people use it for it to be removed, but it is worth getting more opinions about it. -- Zachary P. Landau
I was reading through my major backlog of ruby-talk archives and I found that points out that a proper singleton (ensuring only one instance of a class) could be used to control access to a database that doesn't do concurrency very well.
Also, to the anonymous poster before Zachary, thank you for saying what I was finding difficult to say. The Singleton Pattern is intended to restrict instance creation; the separate MySingletonObjects would actually have separate singleton classes. While the pattern could be generalised to a Pool of objects (with count 1), I think the case of one object and only one object is common enough to warrant Singleton. -- Austin Ziegler
I admit, I left something out, I just wanted to give a hint. To show a working example:
-- Matthias Georgi
IMO if Singleton is to be put into a module/namespace, it should be Antipattern::Singleton, not Pattern::Singleton. Blind use of the singleton pattern makes for code that is difficult to unit test, and I think unit tests are something the Ruby community would like to keep as one of its defining characteristics.
I also think that renaming singleton.rb or moving Singleton to a module solely to reduce confusion with the singleton class is a bad idea (since it will break existing code). Newcomers to Ruby come in with an idea of what "singleton" means already and so they will be confused when they see "singleton class" if it is not explained to them. It would be better to either clearly address this in a FAQ somewhere (explaining the difference between the two and why singleton class is a singleton of its own right), or start a movement to start writing metaclass instead of singleton class.
-- Paul Brannan