digitalmars.D.learn - Pretty fields string
- Andrej Mitrovic (57/57) Feb 29 2012 I've done this a couple of times before but I always had issues, e.g.
- Jacob Carlborg (7/64) Feb 29 2012 Seems like what I have in my serialization library Orange:
- Andrej Mitrovic (2/3) Feb 29 2012 Sweet. I was gonna take a look at Orange for just this purpose. Thanks.
I've done this a couple of times before but I always had issues, e.g.
functions and property calls would be mixed in. But I think I have a
good go-to function now:
import std.algorithm;
import std.conv;
import std.string;
import std.stdio;
import std.range;
struct Foo
{
int one = 1;
property int test() { return 1; }
int three = 3;
string[string] aa;
string toString() { return prettyFieldsString(this); }
}
string prettyFieldsString(T)(T t)
if (is(T == struct) || is(T == class))
{
Appender!string result;
Appender!(string[]) fields;
Appender!(string[]) values;
foreach (member; __traits(allMembers, T))
{
mixin("
static if (!is( FunctionTypeOf!(t." ~ member ~ ") ))
{
static if (member != " ~ `"toString"` ~ ")
{
fields.put(member);
values.put(to!string(__traits(getMember, t, " ~ `"` ~
member ~ `"` ~ ")));
}
}
");
}
size_t spaceLen = 1;
foreach (field; fields.data) // should use reduce!() here..
spaceLen = max(spaceLen, field.length);
alias std.array.replicate replicate;
string spaceString = replicate(" ", spaceLen);
foreach (field, value; lockstep(fields.data, values.data))
result.put(format("%s: %s%s\n", field, replicate(" ", spaceLen
- field.length), value));
return result.data;
}
void main()
{
Foo foo;
foo.aa["foo"] = "bar";
writeln(foo);
}
Sample output: http://paste.pocoo.org/show/558492/
I've had to put everything into one foreach loop since there are still
some CTFE bugs I run into. I also had to add a check against toString,
otherwise I get an infinite loop in the toString() call.
Anyway, feel free to use/improve this function.
Feb 29 2012
On 2012-02-29 10:58, Andrej Mitrovic wrote:
I've done this a couple of times before but I always had issues, e.g.
functions and property calls would be mixed in. But I think I have a
good go-to function now:
import std.algorithm;
import std.conv;
import std.string;
import std.stdio;
import std.range;
struct Foo
{
int one = 1;
property int test() { return 1; }
int three = 3;
string[string] aa;
string toString() { return prettyFieldsString(this); }
}
string prettyFieldsString(T)(T t)
if (is(T == struct) || is(T == class))
{
Appender!string result;
Appender!(string[]) fields;
Appender!(string[]) values;
foreach (member; __traits(allMembers, T))
{
mixin("
static if (!is( FunctionTypeOf!(t." ~ member ~ ") ))
{
static if (member != " ~ `"toString"` ~ ")
{
fields.put(member);
values.put(to!string(__traits(getMember, t, " ~ `"` ~
member ~ `"` ~ ")));
}
}
");
}
size_t spaceLen = 1;
foreach (field; fields.data) // should use reduce!() here..
spaceLen = max(spaceLen, field.length);
alias std.array.replicate replicate;
string spaceString = replicate(" ", spaceLen);
foreach (field, value; lockstep(fields.data, values.data))
result.put(format("%s: %s%s\n", field, replicate(" ", spaceLen
- field.length), value));
return result.data;
}
void main()
{
Foo foo;
foo.aa["foo"] = "bar";
writeln(foo);
}
Sample output: http://paste.pocoo.org/show/558492/
I've had to put everything into one foreach loop since there are still
some CTFE bugs I run into. I also had to add a check against toString,
otherwise I get an infinite loop in the toString() call.
Anyway, feel free to use/improve this function.
Seems like what I have in my serialization library Orange:
https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d
"fieldsOf" and "getValueOfField". These work only on instance variables
and don't care if the variable is public or not.
--
/Jacob Carlborg
Feb 29 2012
On 2/29/12, Jacob Carlborg <doob me.com> wrote:Seems like what I have in my serialization library Orange:Sweet. I was gonna take a look at Orange for just this purpose. Thanks.
Feb 29 2012








Andrej Mitrovic <andrej.mitrovich gmail.com>