immutable singleton pattern with static opCall

Justin Johansson no at spam.com
Mon Jun 28 05:07:40 PDT 2010


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

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 {}
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).

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
   // ..
}


Cheers
Justin


More information about the Digitalmars-d mailing list