digitalmars.D.learn - Getting nice print of struct for debugging
- Martin Tschierschke (24/24) Feb 20 2017 Hello,
- Paul Backus (21/26) Feb 20 2017 I believe the easiest way to do this is to define a custom
- Martin Tschierschke (4/30) Feb 20 2017 Good suggestion, thank you! Then the definition is near the
- Jacob Carlborg (13/33) Feb 21 2017 Yes, this works, I would say this is the simplest:
- Martin Tschierschke (9/20) Feb 22 2017 On Tuesday, 21 February 2017 at 14:02:54 UTC, Jacob Carlborg
- Jacob Carlborg (7/11) Feb 24 2017 It depends. You can create a template mixin containing the
- Minty Fresh (18/43) Feb 24 2017 Since structs are Plain-old Data and don't do inheritance, the
- Minty Fresh (4/23) Feb 24 2017 Errata on that. Should actually be declared as:
- Martin Tschierschke (23/53) Feb 27 2017 Thank you, but this solution from Kevin Brogan, is an good
Hello, I have a little program where I am filling a struct with values from an regex match. Now I want to display the content of the struct for debugging purpose. If struct is named MyStruct I can print a list of the field names with: foreach(fieldname;FieldNameTuple!MyStruct){writef("%s ",fieldname);} If myvar is of type MyStruct how can I make a table like: fieldname_1: value_1 fieldname_2: value_2 . . fieldname_n: value_n Is there a way to do this with a single expression in D. Similar to a ruby call myvar.send(fieldname) to get the value from fieldname inside a loop? write(myvar); sure is working directly but I want to get the field names displayed, too. (A work around might be work with the format("%s",myvar) string and extract the values with an index?) Regards mt.
Feb 20 2017
On Monday, 20 February 2017 at 16:04:17 UTC, Martin Tschierschke wrote:Hello, I have a little program where I am filling a struct with values from an regex match. Now I want to display the content of the struct for debugging purpose.I believe the easiest way to do this is to define a custom toString member function for your struct. For example: struct MyStruct { int x; double y; string s; string toString() { import std.format: format; return "MyStruct(x: %d, y: %f, s: \"%s\")".format(x, y, s); } } void main() { import std.stdio: writeln; MyStruct foo; foo.x =2; foo.y = 3.14; foo.s = "the quick brown fox"; writeln(foo); // Prints MyStruct(x: 2, y: 3.140000, s: "the quick brown fox") }
Feb 20 2017
On Monday, 20 February 2017 at 16:18:58 UTC, Paul Backus wrote:On Monday, 20 February 2017 at 16:04:17 UTC, Martin Tschierschke wrote:Good suggestion, thank you! Then the definition is near the struct definition and I do not need to care about what to call, just writeln(myvar); cool!Hello, I have a little program where I am filling a struct with values from an regex match. Now I want to display the content of the struct for debugging purpose.I believe the easiest way to do this is to define a custom toString member function for your struct. For example: struct MyStruct { int x; double y; string s; string toString() { import std.format: format; return "MyStruct(x: %d, y: %f, s: \"%s\")".format(x, y, s); } } void main() { import std.stdio: writeln; MyStruct foo; foo.x =2; foo.y = 3.14; foo.s = "the quick brown fox"; writeln(foo); // Prints MyStruct(x: 2, y: 3.140000, s: "the quick brown fox") }
Feb 20 2017
On 2017-02-20 17:04, Martin Tschierschke wrote:Hello, I have a little program where I am filling a struct with values from an regex match. Now I want to display the content of the struct for debugging purpose. If struct is named MyStruct I can print a list of the field names with: foreach(fieldname;FieldNameTuple!MyStruct){writef("%s ",fieldname);} If myvar is of type MyStruct how can I make a table like: fieldname_1: value_1 fieldname_2: value_2 . . fieldname_n: value_n Is there a way to do this with a single expression in D. Similar to a ruby call myvar.send(fieldname) to get the value from fieldname inside a loop? write(myvar); sure is working directly but I want to get the field names displayed, too. (A work around might be work with the format("%s",myvar) string and extract the values with an index?)Yes, this works, I would say this is the simplest: MyStruct s; foreach (index, name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, s.tupleof[index]); If you want something more close to "send" in Ruby, you need to use a string mixin, like this: foreach (name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, mixin("s." ~ name)); The string mixin example works for methods, opDispatch and similar as well. The tupleof example, the first one, works only for fields. -- /Jacob Carlborg
Feb 21 2017
On Tuesday, 21 February 2017 at 14:02:54 UTC, Jacob Carlborg wrote: [...]Yes, this works, I would say this is the simplest: MyStruct s; foreach (index, name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, s.tupleof[index]); If you want something more close to "send" in Ruby, you need to use a string mixin, like this: foreach (name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, mixin("s." ~ name)); The string mixin example works for methods, opDispatch and similar as well. The tupleof example, the first one, works only for fields.Exactly what I was looking for, **thank you!** Both ways of accessing the struct elements are very interesting, giving an impression what is possible with D. Is it possible to overwrite "toString" for all structs in one step? Regards mt.
Feb 22 2017
On 2017-02-22 12:18, Martin Tschierschke wrote:Exactly what I was looking for, **thank you!** Both ways of accessing the struct elements are very interesting, giving an impression what is possible with D. Is it possible to overwrite "toString" for all structs in one step?It depends. You can create a template mixin containing the implementation of toString, which need to be mixed in in all structs. Or you can create a new function that can convert any passed in structs in a generic way. It depends on what you need the string for. -- /Jacob Carlborg
Feb 24 2017
On Wednesday, 22 February 2017 at 11:18:15 UTC, Martin Tschierschke wrote:On Tuesday, 21 February 2017 at 14:02:54 UTC, Jacob Carlborg wrote: [...]Since structs are Plain-old Data and don't do inheritance, the best option is a template mixin. ie. template mixin PrettyPrint { string toString() { // . . . } } From there, you can mix it into any struct you want. struct MyStruct { mixin PrettyPrint; } If you're familiar with Rails, this is similar to a Concern.Yes, this works, I would say this is the simplest: MyStruct s; foreach (index, name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, s.tupleof[index]); If you want something more close to "send" in Ruby, you need to use a string mixin, like this: foreach (name ; FieldNameTuple!MyStruct) writefln("%s: %s", name, mixin("s." ~ name)); The string mixin example works for methods, opDispatch and similar as well. The tupleof example, the first one, works only for fields.Exactly what I was looking for, **thank you!** Both ways of accessing the struct elements are very interesting, giving an impression what is possible with D. Is it possible to overwrite "toString" for all structs in one step? Regards mt.
Feb 24 2017
On Saturday, 25 February 2017 at 01:27:09 UTC, Minty Fresh wrote:On Wednesday, 22 February 2017 at 11:18:15 UTC, Martin Tschierschke wrote:Errata on that. Should actually be declared as: mixin template PrettyPrint() This is why I shouldn't make posts from my phone.[...]Since structs are Plain-old Data and don't do inheritance, the best option is a template mixin. ie. template mixin PrettyPrint { string toString() { // . . . } } From there, you can mix it into any struct you want. struct MyStruct { mixin PrettyPrint; } If you're familiar with Rails, this is similar to a Concern.
Feb 24 2017
On Saturday, 25 February 2017 at 01:30:09 UTC, Minty Fresh wrote:On Saturday, 25 February 2017 at 01:27:09 UTC, Minty Fresh wrote:Thank you, but this solution from Kevin Brogan, is an good alternative, to add a special dump function globally, so no need to modify the struct definitions. https://forum.dlang.org/post/yewavntuyutdvejwjamp forum.dlang.org His solution: import std.traits; void main() { WSADATA wsa; dump!wsa; } void dump(alias variable)() { writeln("\nDumping ",typeid(typeof(variable)),":\n"); writeln(variable.stringof, " = \n{"); foreach(member; FieldNameTuple!(typeof(variable))) { writeln("\t", member, ": ", mixin("variable."~member) ); } writeln("}\n"); }On Wednesday, 22 February 2017 at 11:18:15 UTC, Martin Tschierschke wrote:Errata on that. Should actually be declared as: mixin template PrettyPrint() This is why I shouldn't make posts from my phone.[...]Since structs are Plain-old Data and don't do inheritance, the best option is a template mixin. ie. template mixin PrettyPrint { string toString() { // . . . } } From there, you can mix it into any struct you want. struct MyStruct { mixin PrettyPrint; } If you're familiar with Rails, this is similar to a Concern.
Feb 27 2017