www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Anyone have a function to print out the field name and its value?

reply Andrej Mitrovic <none none.none> writes:
Let's say I have this structure:

struct PAINTSTRUCT
{
    bool state;
}

And somewhere in my main code I want to print out the value of state. But I
also want to know what I'm printing out. So usually I'd do this:
void main()
{
    PAINTSTRUCT ps;
    writefln("ps.state = %s", ps.state);
}

Has anyone written a function which will automatically print out both the
variable name and any object it might be part of, and then the value?

E.g. I'd like to use a function like this:
writeField(ps.state);

And if state is false it would print out to the console:
"ps.state = false"

I can't really touch PRINTSTRUCT because it's already defined as a WinAPI
structure and messing with that would be bad, so I can't implement toString()
or any helper functions within the struct. I need an outside function which
could do this automatically for any object/struct type.
Apr 09 2011
next sibling parent Andrej Mitrovic <none none.none> writes:
Andrej Mitrovic Wrote:
 

Actually I couldn't really just use "ps.fErase", because that just passes a bool to the function. Hmm.. this doesn't look possible to do without introducing complexity at the calling site.
Apr 09 2011
prev sibling next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 09/04/2011 18:13, Andrej Mitrovic wrote:
 Let's say I have this structure:

 struct PAINTSTRUCT
 {
      bool state;
 }

 And somewhere in my main code I want to print out the value of state. But I
also want to know what I'm printing out. So usually I'd do this:
 void main()
 {
      PAINTSTRUCT ps;
      writefln("ps.state = %s", ps.state);
 }

 Has anyone written a function which will automatically print out both the
variable name and any object it might be part of, and then the value?

 E.g. I'd like to use a function like this:
 writeField(ps.state);

 And if state is false it would print out to the console:
 "ps.state = false"

 I can't really touch PRINTSTRUCT because it's already defined as a WinAPI
structure and messing with that would be bad, so I can't implement toString()
or any helper functions within the struct. I need an outside function which
could do this automatically for any object/struct type.

Off the top of my head (untested): ---- void print(T)(T t) if (is(T == struct) || is(T == class)) { foreach (i, field; t.tupleof) { writefln(T.tupleof[i].stringof ~ " = %s", field); } } ---- -- Robert http://octarineparrot.com/
Apr 09 2011
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 09/04/2011 18:23, Robert Clipsham wrote:
 Off the top of my head (untested):
 ----
 void print(T)(T t) if (is(T == struct) || is(T == class))
 {
 foreach (i, field; t.tupleof)
 {
 writefln(T.tupleof[i].stringof ~ " = %s", field);
 }
 }
 ----

 --
 Robert
 http://octarineparrot.com/

I forgot to mention... Usage: --- print(myStruct); ---- It's also simple enough to adapt to just print a given field etc. -- Robert http://octarineparrot.com/
Apr 09 2011
parent Robert Clipsham <robert octarineparrot.com> writes:
On 09/04/2011 18:44, Andrej Mitrovic wrote:
 On 4/9/11, Andrej Mitrovic<andrej.mitrovich gmail.com>  wrote:
 That's great, I can use it to print out all the fields. Thanks!

Some error checking should be done, or maybe there's a bug. If a field has a type that is a typedef to say a void*: typedef void* HANDLE struct S { HANDLE hnd; } Printing hnd will fail with an error: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1599): Error: function std.format.formatValue!(LockingTextWriter,HANDLE,immutable(char)).formatValue is deprecated D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(308): Error: template instance std.format.formatGeneric!(LockingTextWriter,HANDLE,immutable(char)) error instantiating D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(701): instantiated from here: formattedWrite!(LockingTextWriter,immutable(char),HANDLE) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1598): instantiated from here: writefln!(string,HANDLE) hello_msg.d(35): instantiated from here: writefln!(string,HANDLE) hello_msg.d(129): instantiated from here: print!(PAINTSTRUCT)

For now you can compile with -d, this should be reported as a bug though.
 Btw, why are we not allowed to have mixin templates that have
 statements? Why only declarations?

Dunno, never made sense to me... Could be a question for d.D. -- Robert http://octarineparrot.com/
Apr 09 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/9/11, Robert Clipsham <robert octarineparrot.com> wrote:
 On 09/04/2011 18:23, Robert Clipsham wrote:
 Off the top of my head (untested):
 ----
 void print(T)(T t) if (is(T == struct) || is(T == class))
 {
 foreach (i, field; t.tupleof)
 {
 writefln(T.tupleof[i].stringof ~ " = %s", field);
 }
 }
 ----

 --
 Robert
 http://octarineparrot.com/

I forgot to mention... Usage: --- print(myStruct); ---- It's also simple enough to adapt to just print a given field etc. -- Robert http://octarineparrot.com/

That's great, I can use it to print out all the fields. Thanks!
Apr 09 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/9/11, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 That's great, I can use it to print out all the fields. Thanks!

Some error checking should be done, or maybe there's a bug. If a field has a type that is a typedef to say a void*: typedef void* HANDLE struct S { HANDLE hnd; } Printing hnd will fail with an error: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1599): Error: function std.format.formatValue!(LockingTextWriter,HANDLE,immutable(char)).formatValue is deprecated D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(308): Error: template instance std.format.formatGeneric!(LockingTextWriter,HANDLE,immutable(char)) error instantiating D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(701): instantiated from here: formattedWrite!(LockingTextWriter,immutable(char),HANDLE) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1598): instantiated from here: writefln!(string,HANDLE) hello_msg.d(35): instantiated from here: writefln!(string,HANDLE) hello_msg.d(129): instantiated from here: print!(PAINTSTRUCT) Btw, why are we not allowed to have mixin templates that have statements? Why only declarations?
Apr 09 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/9/11, Robert Clipsham <robert octarineparrot.com> wrote:
 For now you can compile with -d, this should be reported as a bug though.

Ok, reported. http://d.puremagic.com/issues/show_bug.cgi?id=5825
 Dunno, never made sense to me... Could be a question for d.D.

Yup. :)
Apr 09 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Wow, I figured out a trick. Check it out, two modules:

1. fieldwrite.d:
module fieldwrite;

import std.string;
import std.stdio;
import std.conv;

mixin template field(string T)
{
    struct FieldTemp
    {
        this(string str)
        {
            writefln(str ~ " = %s", mixin(T));
        }
    }

    FieldTemp fieldTemp = FieldTemp(T);
}

2. driver.d:

import std.stdio;
import fieldwrite;

struct S
{
    int x;
    int y;
}

void main()
{
    S s;
    s.x = 1;
    s.y = 2;

    mixin field!"s.x";
    mixin field!"s.y";
}
Apr 09 2011