www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Member Access Based On A Runtime String

reply Jack Stouffer <jack jackstouffer.com> writes:
In Python, I can do this:

     my_obj = Obj()
     string_from_func = func()
     setattr(my_obj, string_from_func, 100)

Say func() returns "member1" or "member2", the setattr would then 
set either one of those to 100.

Is there any equivalent in D?
Feb 29 2016
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 1 March 2016 at 05:05:40 UTC, Jack Stouffer wrote:
 In Python, I can do this:

     my_obj = Obj()
     string_from_func = func()
     setattr(my_obj, string_from_func, 100)

 Say func() returns "member1" or "member2", the setattr would 
 then set either one of those to 100.

 Is there any equivalent in D?
Not built-in. You would have do something similar to what the Python interpreter does. Store pointers to the setter functions in an AA and use the member names as keys.
Feb 29 2016
prev sibling next sibling parent Andrea Fontana <nospam example.com> writes:
On Tuesday, 1 March 2016 at 05:05:40 UTC, Jack Stouffer wrote:
 In Python, I can do this:

     my_obj = Obj()
     string_from_func = func()
     setattr(my_obj, string_from_func, 100)

 Say func() returns "member1" or "member2", the setattr would 
 then set either one of those to 100.

 Is there any equivalent in D?
Maybe if string_from_func can be computed at compile time. Something like this: http://dpaste.dzfl.pl/8bc21da1147a ?
Mar 01 2016
prev sibling parent reply Adrian Matoga <dlang.spam matoga.info> writes:
On Tuesday, 1 March 2016 at 05:05:40 UTC, Jack Stouffer wrote:
 In Python, I can do this:

     my_obj = Obj()
     string_from_func = func()
     setattr(my_obj, string_from_func, 100)

 Say func() returns "member1" or "member2", the setattr would 
 then set either one of those to 100.

 Is there any equivalent in D?
struct Foo { string foo = "dog"; int bar = 42; int baz = 31337; } void set(P, T)(ref P p, string name, auto ref T value) { foreach (mem; __traits(allMembers, P)) { static if (is(typeof(__traits(getMember, p, mem)) Q)) { static if (is(Q : T)) { if (mem == name) { __traits(getMember, p, mem) = value; return; } } } } assert(0, P.stringof ~ " has no member " ~ name); } unittest { Foo foo; foo.set("bar", 15); assert(foo.bar == 15); foo.set("foo", "cat"); assert(foo.foo == "cat"); }
Mar 01 2016
next sibling parent Adrian Matoga <dlang.spam matoga.info> writes:
On Tuesday, 1 March 2016 at 08:53:20 UTC, Adrian Matoga wrote:
 			static if (is(Q : T)) {
Oops, should be T : Q
Mar 01 2016
prev sibling parent Jack Stouffer <jack jackstouffer.com> writes:
On Tuesday, 1 March 2016 at 08:53:20 UTC, Adrian Matoga wrote:
 struct Foo
 {
 	string foo = "dog";
 	int bar = 42;
 	int baz = 31337;
 }

 void set(P, T)(ref P p, string name, auto ref T value)
 {
 	foreach (mem; __traits(allMembers, P)) {
 		static if (is(typeof(__traits(getMember, p, mem)) Q)) {
 			static if (is(Q : T)) {
 				if (mem == name) {
 					__traits(getMember, p, mem) = value;
 					return;
 				}
 			}
 		}
 	}
 	assert(0, P.stringof ~ " has no member " ~ name);
 }

 unittest
 {
 	Foo foo;
 	foo.set("bar", 15);
 	assert(foo.bar == 15);
 	foo.set("foo", "cat");
 	assert(foo.foo == "cat");
 }
Thanks. This should be in Phobos
Mar 01 2016