[phobos] Make Tuple.toString useful

Q. Schroll via phobos phobos at puremagic.com
Tue Aug 25 16:15:40 PDT 2015


I'm new to this, maybe this proposal has been made once and I've 
overseen it.

Tuples only allow the %s format specifier which is rather useless 
except from debugging.

One way to format output a Tuple is expanding it. But this works 
only, when the tuple is outermost, i. e. like in format("%d: 
%.3f", int_float_tuple.expand), and not like in format("%(%d: 
%.3f%)", int_float_tuple_array.map!(t => t.expand)) which 
currently doesn't work.

Therefore I propose to make Tuples also to be formated by %( %) 
and %( %| %).
For the first one, the expression inside is used to format the 
tuple the in the aforementioned way.
The second takes the tuple like an array (one expression and 
separators, not the escaping stuff).

unittest
{
     import std.format   : format;
     import std.typecons : Tuple, tuple;
     alias t = tuple;
     auto if_list = [ t(1, 1.0), t(2, 4.0), t(3, 9.0) ];

     assert(format("%s", t("a", 1))                          == 
`Tuple!(string, int)("a", 1)`);
     assert(format("%(%#x v %.4f w %#x%)", t(1, 1.0, 10))    == 
`0x1 v 1.0000 w 0xa`);
     assert(format("%(q%sq%| x %)", t("abc", 1, 2.3, [4,5])) == 
`qabcq x q1q x q2.3q x q[4, 5]q`);
     assert(format("%(%(%d^2 = %.1f%);  %)", if_list)        == 
`1^2 = 1.0;  2^2 = 4.0;  3^2 = 9.0`);
}

Both can be done. I already have tested it and it works perfectly.

All you have to do:
In typecons.d, line 762, add  std.format.FormatSpec!char fmt = 
"%s"  parameter.
In the function body, add at front
     if (fmt.nested)
     {
         if (fmt.sep)
         {
             foreach (i, Type; Types)
             {
                 static if (i > 0)
                 {
                     sink(fmt.sep);
                 }
                 static if (is(Type == class) && 
is(typeof(Type.init) == shared))
                 {
                     sink(Type.stringof);
                 }
                 else
                 {
                     import std.format : format;
                     sink(format(fmt.nested, field[i]));
                 }
             }
         }
         else
         {
             import std.format : format;
             sink(format(fmt.nested, expand()));
         }
         return;
     }
The rest of the function can be left as it is.

This feature cannot break any code I can imagine.


More information about the phobos mailing list