On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote:
I need to create an app wide singleton instance for my class.
The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests.

I declared this

class Category
{
protected static immutable Category instance_ = new Category;
     Category instance() { return cast(Category)instance_; }
     ...
}

It compiles and the instance should be instantiated at compile time. I couldn't check yet.

The public interface of Category is designed so that the object's state can't be modified and thus remains immutable.

Is this code valid D or is the behavior undefined due to the cast ?


A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ?


I answer to myself on this question because I finally found out.

Creating an app wide singleton object is as simple as this

class Category
{
    this() { assert __ctfe); } // Just to make sure
    private __gshared instance_ = new Info;
    static Category instance() { return _instance; }
}


It works as long as the constructor doesn't reference other global or static variables.

Unfortunately this is what I have in my use case. I had this

final class Info
{
    Info(Category category, string name)
    {
        category_ = category;
        name_ = name;
        assert(__ctfe);
    }
    private string name_;
    private Category category_;
    string name() { return name_; }
    Category category() { return category_; }
}

This class can't be instantiated as compile time because the constructor depends on the global variable Category.instance_.

Category {
    ...
    __gshared Info a1 = new Info(Category.instance(), "I'm a1");
    __gshared Info a2 = new Info(Category.instance(), "I'm a2");
    ...
}


The problem is solved by changing Category into an immutable class and instance. It's Ok in my case because it is immutable. The only inconvenience left is that we can't have mutable references to immutable objects.

But at least now I can write

Info x1 = Cateqory.a1, x2 = Category.a2;
Info x3 = x1, x4;

assert(x3 is x1);
assert(x3 !is x2);
assert(x1.category is x2.category);
assert(x4 is null);

And of course we can also access all the properties of the Info values. Objects are identified by their unique address.

Another problem left is that synchronization

Reply via email to