thisExePath purity

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Sep 20 06:35:27 PDT 2016


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


More information about the Digitalmars-d-learn mailing list