On 9/20/16 12:17 AM, crimaniak wrote:
Hi and thanks all!

On Tuesday, 20 September 2016 at 00:43:10 UTC, Jonathan M Davis wrote:

immutable string executablePath;

shared static this()
{
    import std.file : thisExePath();
    executablePath = thisExePath();
}

This code is good for my needs but I start to think about how to call
thisExePath only if it is really used and come to this solution:

import std.traits: ReturnType, Parameters;

string staticMemoize(alias T, Parms = Parameters!T)() pure
{
    struct Holder(alias T)
    {
        static shared immutable ReturnType!T value;
        shared static this(){ value = T(Parms); }
    }

    return Holder!T.value;
}

unittest
{
    import std.file : thisExePath;
    assert(staticMemoize!thisExePath == thisExePath);
}

Something like this. Need to refine about input parameters, but I hope,
idea is clear.
Unlike the function memoize from phobos staticMemoize really pure. And
unlike proposed solution with ordinary variable staticMemoize is lazy,
because no call - no instantiation.

Yes, but if your code does instantiate it, it is called, even if you don't ever call the function that calls it.

Note that if you don't import the module that contains the static ctor, it should be trimmed by the linker.

I would absolutely caution you from putting static this() inside any template. Unfortunately, due to the way D generates these static constructors, any module that uses staticMemoize, or *imports a module that uses it*, will be marked as having a static constructor, and will potentially create cycles.

-Steve

Reply via email to