On Mon, 28 Jun 2010 08:07:40 -0400, Justin Johansson <n...@spam.com> wrote:

Steven Schveighoffer wrote:
On Sat, 26 Jun 2010 20:19:44 -0400, Michal Minich <michal.min...@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

Reply via email to