Thread overview
Member Access Based On A Runtime String
Mar 01, 2016
Jack Stouffer
Mar 01, 2016
Mike Parker
Mar 01, 2016
Andrea Fontana
Mar 01, 2016
Adrian Matoga
Mar 01, 2016
Adrian Matoga
Mar 01, 2016
Jack Stouffer
March 01, 2016
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?
March 01, 2016
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.
March 01, 2016
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

?
March 01, 2016
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");
}

March 01, 2016
On Tuesday, 1 March 2016 at 08:53:20 UTC, Adrian Matoga wrote:
> 			static if (is(Q : T)) {

Oops, should be T : Q

March 01, 2016
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