(There is a brief question at the end, all stuffing before is context, sorry)
For a while I have been wondering how to create a singleton class in Newspeak, because the usual trick of storing the singleton instance in a static state cannot be used in Newspeak (yes, for example in Java only works within the same classloader etc, but anyway)
I realize that one way of achieving the goal practically in Newspeak, is to put a slot with the instance on the top class, something like
|modulesSingletonInstance = AnyClass new| (* new or declared primary factory *)
Assuming a developer coding in that module knows and accepts some rigor, any code in the module can address the 'modulesSingletonInstance' because it is in lexical scope, and things should work as needed. But ignorance allows developer to use in code deep inside the module, something like
secondInstance:: AnyClass new.
I thought the way to make an appropriate singleton would be to make the singleton a nested class in the module and:
- make the primary factory private
- provide a public class method getInstance
- still use a slot on the top level class (similar to the |modulesSingletonInstance| above) to store the instance (what would be a static instance in other languages).
I thought it could be something like this (this is overengineered, this is pasted from my test)
-----------------------------
Newspeak3
'Root'
class AAModuleUsingSingletonQUESTION = (
|
(* Holder of the singleton instance for this module. *)
private modulesSingletonInstance <AASingleton>
|
) (
private class AASingleton new = () (
) : (
public getInstance ^<AASingleton> = (
modulesSingletonInstance = nil
ifTrue: [
modulesSingletonInstance: AASingleton new.
].
^ modulesSingletonInstance.
)
)
class NestedUsingSingleton = (
|
public nestedClassSlotWithSingletonInstance = AASingleton getInstance.
|
) (
) : (
)
public client1OfSingleton ^ <AASingleton> = (
|gotInstance|
gotInstance:: AASingleton getInstance.
^ gotInstance.
)
public client2OfSingleton ^ <AASingleton> = (
|gotInstance|
gotInstance:: AASingleton getInstance.
^ gotInstance.
)
public client3OfSingletonUsedInNested ^ <AASingleton> = (
^ NestedUsingSingleton new nestedClassSlotWithSingletonInstance.
)
public client4OfSingletonBreakingSingleton ^ <AASingleton> = (
(* BREAKING SINGLETON *)
modulesSingletonInstance = AASingleton new.
)
) : (-----------------------------
But I did NOT realize, the PRIVATE primary factory
'private class AASingleton new = ()'
does NOT prevent being called from the outer class 'AAModuleUsingSingletonQUESTION', as 'AASingleton' is a member of 'AAModuleUsingSingletonQUESTION', hence accessible, as in the 'client4OfSingletonBreakingSingleton', breaking the singleton property.
Hmm, long context introduction again.
==> My question is, how would a singleton be done right in Newspeak, or are there examples to point to? (I did not yet experiment with importing AASingleton instead of nesting it, maybe I could work around the accessibility rules)
Thanks,
Milan
PS: I promised myself not to overload and only ask 2 short questions a week max. This already exceeded the length, although not the max :)