setting fields of object using traits
I'm trying to set fields of object from JSON with traits library. How i can to it properly? import std.stdio; import std.json; import std.traits; import std.meta: Alias; class Obj{ void fromJSON(this T)(JSONValue j){ foreach(field; FieldNameTuple!T){ alias member = Alias!(__traits(getMember, T, field)); static if (__traits(hasMember, member, "fromJSON")){ member.fromJSON(j[field]); } else { member = j[field]; } } } } class A : Obj{ int a,b; C c; this(){ c = new C(); } } class C : Obj{ int a; this(){ a = 0; }; } int main(string[] argv) { string s = "{\"a\": 1, \"b\": 2, \"c\": {\"a\": 3} }"; JSONValue j = parseJSON(s); A a = new A(); a.fromJSON(j); writeln(a.b); readln(); return 0; } main.d(14): Error: need 'this' for 'a' of type 'int' main.d(14): Error: need 'this' for 'b' of type 'int' main.d(12): Error: template main.Obj.fromJSON cannot deduce function from argument types !(c)(JSONValue), candidates are: main.d(8):main.Obj.fromJSON(this T)(JSONValue j) main.d(41): Error: template instance main.Obj.fromJSON!(A) error instantiating
Re: Metaprogramming with traits
On Friday, 16 September 2016 at 08:01:18 UTC, Gary Willoughby wrote: On Thursday, 15 September 2016 at 22:05:55 UTC, Ram_B wrote: test.d(33): Error: variable f cannot be read at compile time test.d(33): Error: string expected as second argument of __traits hasMember instead of __error test.d(46): Error: template instance test.A.t!(B) error instantiating Maybe Array!(string) can't be use in compile-time code? Which type of array i may use to pass it to compile-time function?
Re: Metaprogramming with traits
On Thursday, 15 September 2016 at 15:56:56 UTC, Gary Willoughby wrote: On Thursday, 15 September 2016 at 15:07:09 UTC, Ram_B wrote: How i can get fields of derived classes in runtime? This not works What about something like this: import std.traits; import std.stdio; class A { int a,b; this(){} void fields(this T)(){ writeln(FieldNameTuple!(T)); foreach(Class; TransitiveBaseTypeTuple!(T)) { writeln(FieldNameTuple!(Class)); } } } class B : A{ int c; this(){} } class C : B{ int d; this(){} } void main(){ C c = new C(); c.fields(); } This works, but i can't use (get|has)Member class A{ int a, b; Array!string fields(this T)(){ Array!string list; foreach(field; FieldNameTuple!(T)){ list.insertBack(field); } foreach(Class; TransitiveBaseTypeTuple!(T)){ foreach(field; FieldNameTuple!(Class)){ list.insertBack(field); } } return list; } void t(this T)(){ foreach(f; this.fields()){ log(__traits(hasMember, T, f)); } } } class B : A{ int c; this(){} } void main(){ B b = new B(); b.t(); } test.d(33): Error: variable f cannot be read at compile time test.d(33): Error: string expected as second argument of __traits hasMember instead of __error test.d(46): Error: template instance test.A.t!(B) error instantiating
Re: Metaprogramming with traits
On Thursday, 15 September 2016 at 15:56:56 UTC, Gary Willoughby wrote: On Thursday, 15 September 2016 at 15:07:09 UTC, Ram_B wrote: How i can get fields of derived classes in runtime? This not works What about something like this: import std.traits; import std.stdio; class A { int a,b; this(){} void fields(this T)(){ writeln(FieldNameTuple!(T)); foreach(Class; TransitiveBaseTypeTuple!(T)) { writeln(FieldNameTuple!(Class)); } } } class B : A{ int c; this(){} } class C : B{ int d; this(){} } void main(){ C c = new C(); c.fields(); } Thanks very much! :3
Metaprogramming with traits
How i can get fields of derived classes in runtime? This not works import std.traits; import std.experimental.logger; class A { int a,b; this(){} void fields(){ log(FieldNameTuple!this); } } class B : A{ int c; this(){} } void main(){ B b = new B(); b.fields(); }