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