Trying to learn, I don't found a Singleton class in Squeak ( maybe exist whit another name ? )
So following http://www.eli.sdsu.edu/courses/spring01/cs635/notes/singleton/singleton.htm l We could have:
Object subclass: #Singleton instanceVariableNames: '' classVariableNames: 'UniqueInstance ' poolDictionaries: '' category: 'Kernel-Classes'
current UniqueInstance ifNil: [UniqueInstance := Singleton basicNew]. ^UniqueInstance
new self error: 'Use current to get an instance of Class ' , self name
Wish to know:
1) If exist this with another name 2) In case not, why not 3) How could hurt me (us) if we have this
Thanks in advance.
Edgar
___________________________________________________________ 1GB gratis, Antivirus y Antispam Correo Yahoo!, el mejor correo web del mundo http://correo.yahoo.com.ar
On 12/2/05, Lic. Edgar J. De Cleene edgardec2001@yahoo.com.ar wrote:
Trying to learn, I don't found a Singleton class in Squeak ( maybe exist whit another name ? )
The code you've posted is a pattern - if you have a class where you want a singleton instance, you use this code in that class. There's no need for a seperate class to handle this.
Cees De Groot puso en su mail :
The code you've posted is a pattern - if you have a class where you want a singleton instance, you use this code in that class. There's no need for a seperate class to handle this
I reading more about this, and found this by Stef
http://www.iam.unibe.ch/~ducasse/Web/OldSmalltalkFiles/Singleton.pdf.
But something still seem unsolved if for having a needed behavior (what only exist one instance of MyClassFoo) we have type (or copy) a piece os same code several times.
Anyway, I follow you advice and thanks you.
Edgar
___________________________________________________________ 1GB gratis, Antivirus y Antispam Correo Yahoo!, el mejor correo web del mundo http://correo.yahoo.com.ar
No, you shouldn't :-) But this is a well-known problem in meta-programming
The reason why you cannot do this in smalltalk is because, when you have a class A and a subclass B, the metaclass of B (being 'B class') must be a subclass of the metaclass of A (being 'A class'). (The reason for this is to guarantee upward and downward compatibility - see links below. In CLOS, one is allowed to choose any metaclass in the class definition, but no compatibility is guaranteed)
A better example is the concept of an abstract class, with concrete subclasses: A is an abstract class, so 'A class>>new' raises an error (like with a singleton) B is a subclass of A, inheriting all behaviour from A, and 'B class' (a concrete class) is a subclass of 'A class': a concrete class inheriting its behaviour from an abstract class. So it is not always conceptually right for classes and their metaclasses to inherit in parallel.
This paper explains the problem clearly and proposes a solution which uses code (and class) generation Safe Metaclass Programming (1998) ( Noury M.N. Bouraqadi-Saâdani, Thomas Ledoux, Fred Rivard) http://citeseer.ist.psu.edu/37617.html
This paper uses traits for metaclass programming Uniform and safe metaclass composition (Stéphane Ducasse, Nathanael Schärli, Roel Wuyts) http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf
(sorry if I have told incorrect things, I'm actually quite new to all this :-) )
On 12/3/05, Philippe Marschall philippe.marschall@gmail.com wrote:
There's no need for a seperate class to handle this.
I disagree. Should I really have to duplicate this code every time I want a new singleton class?
This paper uses traits for metaclass programming Uniform and safe metaclass composition (Stéphane Ducasse, Nathanael Schärli, Roel Wuyts) http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf
So there really should be a singleton trait?
stijn timbermont puso en su mail :
No, you shouldn't :-) But this is a well-known problem in meta-programming
The reason why you cannot do this in smalltalk is because, when you have a class A and a subclass B, the metaclass of B (being 'B class') must be a subclass of the metaclass of A (being 'A class'). (The reason for this is to guarantee upward and downward compatibility - see links below. In CLOS, one is allowed to choose any metaclass in the class definition, but no compatibility is guaranteed)
A better example is the concept of an abstract class, with concrete subclasses: A is an abstract class, so 'A class>>new' raises an error (like with a singleton) B is a subclass of A, inheriting all behaviour from A, and 'B class' (a concrete class) is a subclass of 'A class': a concrete class inheriting its behaviour from an abstract class. So it is not always conceptually right for classes and their metaclasses to inherit in parallel.
This paper explains the problem clearly and proposes a solution which uses code (and class) generation Safe Metaclass Programming (1998) ( Noury M.N. Bouraqadi-Saâdani, Thomas Ledoux, Fred Rivard) http://citeseer.ist.psu.edu/37617.html
This paper uses traits for metaclass programming Uniform and safe metaclass composition (Stéphane Ducasse, Nathanael Schärli, Roel Wuyts) http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf
stijn Very thanks !!. Useful reading.
On Sat, Dec 03, 2005 at 12:02:30PM +0100, Philippe Marschall wrote:
There's no need for a seperate class to handle this.
I disagree. Should I really have to duplicate this code every time I want a new singleton class?
Yes. If you add up all the duplicated singleton code in the known universe, it adds up to fewer bytes than you are going to expend on discussing how to solve the "problem."
Dave
We could have:
Object subclass: #Singleton instanceVariableNames: '' classVariableNames: 'UniqueInstance ' poolDictionaries: '' category: 'Kernel-Classes'
current UniqueInstance ifNil: [UniqueInstance := Singleton basicNew]. ^UniqueInstance
new self error: 'Use current to get an instance of Class ' , self name
I'm not understanding how this would work as a superclass. current should return the object of one of Singleton's child classes, not the object of the Singleton class (which shouldn't exist anyway given that Singleton should be an abstract class). Because I don't know of a simple way of calling down an inheritance hierarchy, I'm thinking that Singleton>>current can best be implemented as a subclass responsibility, which runs counter to factoring common code in a superclass (or suggests that there may not be a useful amount of factorable common code among singleton implementations).
In case not, why not
Assuming the previous objection can be dealt with, the need for a class variable per singleton class causes a problem. For example, if I make both SymbolTable and TypeTable subclasses of Singleton, then the return value for both SymbolTable>>current and TypeTable>>current is set by whichever of SymbolTable>>current or TypeTable>>current is called first, an unhappy event for the current method called second.
There's a few ways to fix this. One is move UniqueInstance down into the child classes too, at which point we can end the discussion as to why there's no Singleton class in Squeak (assuming there isn't one; I don't know for sure). Another is to implement a registry of Singletons (Design Patterns, page 130), which is a loss if you're interested in making code simpler and smaller.
On Dec 3, 2005, at 9:56 AM, R. Clayton wrote:
We could have:
Object subclass: #Singleton instanceVariableNames: '' classVariableNames: 'UniqueInstance ' poolDictionaries: '' category: 'Kernel-Classes'
current UniqueInstance ifNil: [UniqueInstance := Singleton basicNew]. ^UniqueInstance
new self error: 'Use current to get an instance of Class ' , self name
I'm not understanding how this would work as a superclass. current should return the object of one of Singleton's child classes, not the object of the Singleton class (which shouldn't exist anyway given that Singleton should be an abstract class). Because I don't know of a simple way of calling down an inheritance hierarchy, I'm thinking that Singleton>>current can best be implemented as a subclass responsibility, which runs counter to factoring common code in a superclass (or suggests that there may not be a useful amount of factorable common code among singleton implementations).
The answer to your particular problem here is to use a class-instance variable instead of a class variable.
The practical difference between class-instance variables and class variables is that class-instance variables have a unique value for each subclass inheriting the variable, while class variables do not. This is exactly what you're looking for. (It's pretty rare that class-instance variables are needed, but this is one case. Rare enough that I've forgotten whether the convention is to capitalize the variable name or not. ;-) I would guess uncapitalized.)
So:
Object subclass: #Singleton instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Classes'
(and on the class side... )
Singleton class instanceVariableNames: 'uniqueInstance'
current uniqueInstance ifNil: [uniqueInstance := self basicNew]. ^uniqueInstance
So now if you have SymbolTable and TypeTable as subclasses of Singleton, the return value for SymbolTable>>current and TypeTable>>current is different for each.
Anyway, I generally agree with Cees/David that it's not really worth creating a special Singleton superclass for such a tiny amount of behavior. This limits you from subclassing against a more substantial class.
I guess this is a classic case for using something like a Trait (TSingleton), which is probably why it's one of the examples in that Traits paper that stijn mentioned.
- Doug
squeak-dev@lists.squeakfoundation.org