On Tuesday, 18 March 2014 at 21:56:32 UTC, Chris Williams wrote:
import fs = std.file;
import std.stdio;

template gotoPath(alias path) {
    enum gotoPath = q{
        string currPath = fs.getcwd();
        scope (exit) fs.chdir(currPath);
        fs.chdir(path);
    };

This is just a string. The occurence of "path" in it has no
relation to the template parameter path. "path" is mixed in
literally. The template parameter is unused.

}

void doStuff(string targetDirectory) {
    mixin(gotoPath!(targetDirectory));
    writefln("b %s", fs.getcwd());
}

void main() {
    writefln("a %s", fs.getcwd());
    doStuff("/etc");
    writefln("c %s", fs.getcwd());
}


When I try to compile (DMD 2.064), I get the following error:

test.d(16): Error: undefined identifier path

You can pass the variable name as a string:

     import std.string: format;
     template gotoPath(string pathVar) {
         enum gotoPath = format(q{
             ...
             fs.chdir(%s);
         }, pathVar);
     }
     ...
     mixin(gotoPath!"targetDirectory");

Or you can get the variable name from the alias parameter:

     import std.string: format;
     template gotoPath(alias path) {
         enum gotoPath = format(q{
             ...
             fs.chdir(%s);
         }, path.stringof);
     }

I think I've read that .stringof shouldn't be used for code
generation, but I can't think of anything better.

Then there's the struct destructor version:

     struct GotoPath
     {
         private string currPath;
         this(string path)
         {
             currPath = fs.getcwd();
             fs.chdir(path);
         }
         ~this()
         {
             fs.chdir(currPath);
         }
     }

Ideally, it would be used like this:

with(GotoPath(targetDirectory)) writefln("b %s", fs.getcwd());

which would be beautiful, if you ask me. But a compiler bug [1]
ruins that. You can still use it with a dummy variable:

     auto dummy = GotoPath(targetDirectory);
     writefln("b %s", fs.getcwd());

[1] https://d.puremagic.com/issues/show_bug.cgi?id=8269

Reply via email to