Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
February 20, 2017 Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
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. |
February 20, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Tschierschke | 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")
}
|
February 20, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | 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:
>> 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")
> }
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!
|
February 21, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Tschierschke | 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 |
February 22, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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.
|
February 24, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Tschierschke | 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 |
February 25, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin Tschierschke | 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:
> [...]
>> 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.
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.
|
February 25, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Minty Fresh | 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:
>> [...]
>
> 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.
Errata on that. Should actually be declared as:
mixin template PrettyPrint()
This is why I shouldn't make posts from my phone.
|
February 27, 2017 Re: Getting nice print of struct for debugging | ||||
---|---|---|---|---|
| ||||
Posted in reply to Minty Fresh | 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: >> On Wednesday, 22 February 2017 at 11:18:15 UTC, Martin Tschierschke 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. > > Errata on that. Should actually be declared as: > > mixin template PrettyPrint() > > This is why I shouldn't make posts from my phone. 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"); } |
Copyright © 1999-2021 by the D Language Foundation