www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Find variable at run time

reply "Josh" <moonburntm gmail.com> writes:
Instead of doing this:

void main()
{
     int x, y, z;
     write("Increment which variable: ");
     string input = readln()[0..$ - 1];
     final switch (input)
     {
         case "x":
             x++;
             break;
         case "y":
             y++;
             break;
         case "z":
             z++;
             break;
     }
     writeln(x, y, z);
}

Is something like this possible in D?

void main()
{
     int x, y, z;
     write("Increment which variable: ");
     string input = readln()[0..$ - 1];
     findVar(input)++;
     writeln(x, y, z);
}

Thanks

Josh
May 17 2013
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
Not with local variables, but you can with a struct.

===

import std.stdio;

void main() {
	struct Vars {
		int x;
		int y;
		int z;

		ref int get(string name) {
                       // allMembers gets the names of each member 
as a string
			foreach(member; __traits(allMembers, typeof(this))) {
                                // we're only interested in ints 
because string++ doesn't make sense anyway
				static if(is(typeof(__traits(getMember, this, member)) == 
int)) {
					if(member == name)
						return __traits(getMember, this, member);
				}
			}
			throw new Exception("I don't know " ~ name);
		}

	}

	Vars vars;

	writeln("which variable?");
	vars.get(readln[0 .. $-1])++;
	writeln(vars.x, vars.y, vars.z);
}

===
May 17 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Josh:

 Is something like this possible in D?

 void main()
 {
     int x, y, z;
     write("Increment which variable: ");
     string input = readln()[0..$ - 1];
     findVar(input)++;
     writeln(x, y, z);
 }
The Go language and its standard library make the usage of such runtime reflection much simpler than in D. So I think D has to improve on such things. A starting point: import std.stdio, std.string; void main() { int x, y, z; auto findVar = ["x": &x, "y": &y, "z": &z]; "Increment which variable: ".write; const input = readln.chomp; (*findVar[input])++; writeln(x, y, z); } With __FUNCTION__ you can tell the name of the current function, but how do you find the caller function? And how do you find the names of the local variables in the caller function? D is a statically compiled language, and its templates allow to do lot of stuff at compile-time. But some run-time reflection is handy in many cases. Bye, bearophile
May 17 2013
parent reply "Josh" <moonburntm gmail.com> writes:
On Friday, 17 May 2013 at 22:15:09 UTC, bearophile wrote:
 Josh:

 Is something like this possible in D?

 void main()
 {
    int x, y, z;
    write("Increment which variable: ");
    string input = readln()[0..$ - 1];
    findVar(input)++;
    writeln(x, y, z);
 }
The Go language and its standard library make the usage of such runtime reflection much simpler than in D. So I think D has to improve on such things. A starting point: import std.stdio, std.string; void main() { int x, y, z; auto findVar = ["x": &x, "y": &y, "z": &z]; "Increment which variable: ".write; const input = readln.chomp; (*findVar[input])++; writeln(x, y, z); } With __FUNCTION__ you can tell the name of the current function, but how do you find the caller function? And how do you find the names of the local variables in the caller function? D is a statically compiled language, and its templates allow to do lot of stuff at compile-time. But some run-time reflection is handy in many cases. Bye, bearophile
Bearophile, is your findVar an AA? It looks like it is, I just didn't think you could put refs in an AA. Thanks Josh
May 17 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Saturday, 18 May 2013 at 02:09:49 UTC, Josh wrote:
 Bearophile, is your findVar an AA? It looks like it is, I just 
 didn't think you could put refs in an AA.

 Thanks

 Josh
It is AA and it stores pointers, not references. P.S. There can be found a lot of solutions but they will all do some kind of adding extra run time information, be it "if" chain or AA map. Local variable names exist only during compilation, in compiled binary those are just stack offsets so can't possibly find one based on run time value without that extra info.
May 18 2013
parent "Josh" <moonburntm gmail.com> writes:
On Saturday, 18 May 2013 at 08:26:09 UTC, Dicebot wrote:
 On Saturday, 18 May 2013 at 02:09:49 UTC, Josh wrote:
 Bearophile, is your findVar an AA? It looks like it is, I just 
 didn't think you could put refs in an AA.

 Thanks

 Josh
It is AA and it stores pointers, not references. P.S. There can be found a lot of solutions but they will all do some kind of adding extra run time information, be it "if" chain or AA map. Local variable names exist only during compilation, in compiled binary those are just stack offsets so can't possibly find one based on run time value without that extra info.
Ah, thanks for that. Josh
May 18 2013