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