immutable singleton pattern with static opCall
Steven Schveighoffer
schveiguy at yahoo.com
Mon Jun 28 05:19:53 PDT 2010
On Mon, 28 Jun 2010 08:07:40 -0400, Justin Johansson <no at spam.com> wrote:
> Steven Schveighoffer wrote:
>> On Sat, 26 Jun 2010 20:19:44 -0400, Michal Minich
>> <michal.minich at gmail.com> wrote:
>>
>>> On Sun, 27 Jun 2010 09:36:04 +0930, Justin Johansson wrote:
>>>
>>>> immutable class Foo
>>>> {
>>>> static private Foo instance;
>>>>
>>>> static this() { // line 9
>>>> instance = new Foo;
>>>> }
>>>>
>>>> static Foo opCall() { // line 13
>>>> return instance;
>>>> }
>>>> }
>>>>
>>>> test.d(9): Error: function test.Foo._staticCtor2 without 'this' cannot
>>>> be const/immutable
>>>> test.d(13): Error: function test.Foo.opCall without 'this' cannot be
>>>> const/immutable
>>>
>>> there is bug report on this subject
>>>
>>> http://d.puremagic.com/issues/show_bug.cgi?id=3598
>>>
>>> Your example also uses static variable, which was not considered in the
>>> bug report. This makes things more complex to design properly, because
>>> it
>>> seems now that one does not want static functions to be affected by
>>> immutable attribute of class, but it should affect static data...
>> static variables inside an immutable class should be immutable. That
>> was considered in the bug report and purposefully left out.
>> The issue is that the compiler incorrectly labels static *functions*
>> as immutable which makes no sense, static functions cannot be immutable
>> ever. Static data can be.
>> BTW, you can work around this problem like this:
>> class Foo
>> {
>> static immutable instance; // no need to make private, it can never
>> change
>> static this() {
>> instance = new Foo; // not sure if this works, you may have to
>> cast.
>> }
>> static immutable(Foo) opCall() {
>> return instance;
>> }
>> immutable:
>> // member functions
>> }
>> -Steve
>
> Thanks Steve.
>
> btw. The reason I marked the static instance member as private
> was simply to enforce stylist use of Foo() rather than Foo.instance
Yuck Foo().xyz :)
But, whatever floats your boat.
>
> You guess is correct; I found that you have to use a cast with
> instance = new Foo
> but then I discovered that you can avoid the cast by writing
> a trivial constructor marked with immutable, i.e.
> immutable this {}
Ah, that is good. However, I was also unsure if a static immutable could
be set inside a static constructor. That is also good, immutable has
definitely gotten a lot easier to use!
> Though this doesn't reduce the headcount of the uses of the immutable
> keyword, I think it looks nicer than a cast. Your idea of immutable:
> though is good for the remainder of the member functions (and the
> trivial ctor).
I have a feeling that the afore mentioned bug will eventually be fixed,
and at that point, you can just make Foo an immutable class with no issues.
>
> My immutable singleton pattern now looks like this :-)
>
>
> class Foo
> {
> // following marked private for stylistic enforcement
> static immutable private Foo instance;
>
> static this() {
> // following works without cast thanks to immutable ctor
> instance = new Foo;
> }
>
> static immutable(Foo) opCall() {
> return instance;
> }
>
> immutable:
> this() {}
>
> // more immutable member function decls following
> // ..
> }
To go one step further, if you want it to truly be a singleton type, you
should mark the constructor private.
-Steve
More information about the Digitalmars-d
mailing list