Bug 12791 – .tupleof does not take base class fields into account
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-05-23T15:51:00Z
Last change time
2015-06-30T04:45:24Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-05-23T15:51:28Z
-----
class A
{
int a;
}
class B : A
{
int b;
B clone()
{
auto b = new B;
b.tupleof = this.tupleof;
return b;
}
}
void main()
{
auto b = new B;
b.a = 10;
b.b = 20;
auto clone = b.clone();
assert(clone.b == 20);
assert(clone.a == 10); // fails, it's 0
}
-----
Since working with .tupleof is a fairly new and experimental feature I think the above could be labeled an enhancement request.
Comment #1 by andrej.mitrovich — 2014-05-23T15:58:40Z
Nevermind, just saw the docs:
-----
The .tupleof property returns an $(I ExpressionTuple)
of all the fields in the class, excluding the hidden fields and the
fields in the base class.
-----
It's a shame because it makes deep object copying more complicated than a simple one-liner. Perhaps we could use some kind of Phobos helper template to implement deep-dup-ing.
Comment #2 by pabuond — 2015-06-29T15:59:09Z
I have been trying to find a way to dynamically retrieve all the fields of a derived class (and their value), including of course those of the base class.
As you say and as described in the doc, `.tupleof` doesn't return fields from the base class (why?)
Traits only help for static fields, and calling `myclassinstance.super.tupleof` doesn't work, nor does `myclassinstance.BaseClassName.tupleof` (as suggested in http://forum.dlang.org/post/[email protected])
Is there any way?
Comment #3 by pabuond — 2015-06-30T04:45:24Z
ok, sorry, indeed __traits can do it. I know this may be out of place here but might still be useful for people landing on this page:
-----------
auto b = new B; // B inherits from A
foreach(i, m; __traits(allMembers, B))
static if (__traits(compiles, to!string(__traits(getMember, b, m))))
writeln(m, " = ", __traits(getMember, b, m));
-----------
prints 'name = value' for all the fields (inherited or new, static or not, etc.) of an instance of class B.