Alias template param - Undefined Identifier

anonymous anonymous at example.com
Tue Mar 18 15:42:19 PDT 2014


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


More information about the Digitalmars-d-learn mailing list