-
-
Notifications
You must be signed in to change notification settings - Fork 705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
format should include class field values #9603
Labels
Comments
andrej.mitrovich (@AndrejMitrovic) commented on 2013-04-04T00:32:34ZWorkaround:
private mixin template genToString()
{
override string toString()
{
import std.array;
import std.conv;
import std.string;
Appender!(string[]) result;
foreach (val; this.tupleof)
{
result ~= to!string(val);
}
return format("%s(%s)", __traits(identifier, typeof(this)),
result.data.join(", "));
}
}
class C
{
int x, y;
mixin genToString;
} |
andrej.mitrovich (@AndrejMitrovic) commented on 2013-04-04T11:49:19ZHow's this for a funky workaround:
diff --git a/std/format.d b/std/format.d
index 8896e38..84169c0 100644
--- a/std/format.d
+++ b/std/format.d
@@ -2512,15 +2512,32 @@ if (is(T == class) && !is(T == enum))
put(w, "null");
else
{
+ Object o = val; // workaround
+ string delegate() dg = &o.toString;
+
static if (hasToString!(T, Char) > 1 || (!isInputRange!T && !is(BuiltinTypeOf!T)))
{
- formatObject!(Writer, T, Char)(w, val, f);
+ if (dg.funcptr != &Object.toString)
+ formatObject!(Writer, T, Char)(w, val, f);
+ else
+ {
+ enum ident = __traits(identifier, T);
+
+ mixin(format(q{
+ static struct %s
+ {
+ typeof(T.tupleof) fields;
+ }
+ %s s;
+ s.fields = val.tupleof;
+ }, ident, ident));
+
+ formatValue(w, s, f);
+ }
}
else
{
//string delegate() dg = &val.toString;
- Object o = val; // workaround
- string delegate() dg = &o.toString;
if (dg.funcptr != &Object.toString) // toString is overridden
{
formatObject(w, val, f);
Yeah it's just a joke. But it works. :P |
lt.infiltrator commented on 2015-12-02T17:18:01ZI like it. Have you put in a PR yet? |
dlang-bugzilla (@CyberShadow) commented on 2017-07-07T16:43:58Z(In reply to Andrej Mitrovic from comment #2)
> + if (dg.funcptr != &Object.toString)
Pretty devious. I think it's not unreasonable. |
andrej.mitrovich (@AndrejMitrovic) commented on 2022-07-04T17:09:03ZI think the really consistent part about formatting in Phobos is that the output tends to be semantically-correct syntax.
S(0, 0) is correct as you can construct an instance of `S` this way. But `C(0, 0)` would be semantically incorrect as that's not how classes are constructed. You'd (likely) need to use `new C` and you'd have to care about which constructors are actually implemented, so `new C(0, 0)` might not even be semantically correct either.
Perhaps instead of changing default formatting a better option would be to have a format spec that dumps out the entire representation of the aggregate. "%s" is taken but we could introduce something else.
We could also just close this as WONTFIX. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
andrej.mitrovich (@AndrejMitrovic) reported this on 2013-04-04T00:27:25Z
Transfered from https://issues.dlang.org/show_bug.cgi?id=9872
CC List
Description
This is an unfortunate inconsistency: import std.stdio; import std.string; struct S { int x, y; } class C { int x, y; } void main() { auto s1 = format("%s", S()); auto s2 = format("%s", new C()); writeln(s1); // S(0, 0) writeln(s2); // test.C } It forces us to either always define a toString() method or call some custom user-provided formatting function. format() should try to print the values of the class fields if the toString method is not defined.The text was updated successfully, but these errors were encountered: