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