Lucho La Frazia
Lucho La Frazia

Reputation: 51

uniqueInstance on Seaside Smalltalk

I'm trying to implement the Singleton pattern on Seaside. Here is my code:

        uniqueInstance
            uniqueInstance ifNil: [ uniqueInstance := self createInstance].
            ^ uniqueInstance

    createInstance
        ^ self basicNew

initialize
    users:= OrderedCollection new.

On the instance side I have users that is the instance variable. When I call Application uniqueInstance initialize works. When I inspect the users variable, it said "Identity Set" instead of an OrderedCollection.

Can anybody give me a solution to my mistake?

Upvotes: 1

Views: 147

Answers (2)

Peter Uhnak
Peter Uhnak

Reputation: 10217

Based on a (Pharo) mailing list discussion regarding singletons I wrote about some variations some time ago https://www.peteruhnak.com/blog/2015/12/06/singleton-variations/ .

But the gist of the singleton is:

  1. (usually) block MyThing class>>new
    • because it is a singleton
  2. call super new or self basicNew initialize when creating the instance
    • this is to go around the blocked new; if your dialect doesn't call initialize automatically then use the latter form
  3. (optionally) add MyThing class>>reset to nil the instance
    • for convenience mostly (with <script: 'self reset'> pragma can be made even better)

So in your case it can be something like this:

Users class>>uniqueInstance
    ^ uniqueInstance ifNil: [ uniqueInstance := super new ]

Users class>>new
    self error: 'Users is a singleton -- send uniqueInstance instead'

Users>>initialize
    users:= OrderedCollection new

And if you are in Pharo, feel free the explore the existing implementations

MessageBrowser browse: (#uniqueInstance implementors select: #isMetaSide).
MessageBrowser browse: (#default implementors select: #isMetaSide).
MessageBrowser browse: (#current implementors select: #isMetaSide).

Upvotes: 3

Leandro Caniglia
Leandro Caniglia

Reputation: 14858

Your #createInstance method sends the #basicNew message, but this one doesn't send #initialize. So nobody is initializing your object and users remains nil. There must be some lazy method that sets users to an IndentitySet and that's why you get that. But no one is making it an OrderedCollection.

To initialize the instance use #new instead of #basicNew; at least in Pharo and some other dialects #new will send #initialize for you.

Upvotes: 3

Related Questions