Thread overview
[phobos] Make Tuple.toString useful
Aug 25, 2015
Q. Schroll
Aug 27, 2015
Q. Schroll
Aug 27, 2015
Jonathan M Davis
August 25, 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.
_______________________________________________
phobos mailing list
phobos@puremagic.com
http://lists.puremagic.com/mailman/listinfo/phobos
August 27, 2015
The best way to do something like this is to create a pull request. This will not only give you credit for the change and make the code easy to add to Phobos, but it will make sure it doesn’t break any existing tests.

Please have a look here: http://wiki.dlang.org/Pull_Requests <http://wiki.dlang.org/Pull_Requests>

-Steve

> On Aug 25, 2015, at 7:15 PM, Q. Schroll via phobos <phobos@puremagic.com> wrote:
> 
> 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.
> _______________________________________________
> phobos mailing list
> phobos@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos



August 27, 2015
On Tuesday, August 25, 2015 23:15:40 Q. Schroll via phobos wrote:
> I'm new to this, maybe this proposal has been made once and I've overseen it.
[snip]

You _might_ get some discussion is this list, but it's been a long time since much discussion went on here. That discussion has mostly moved to either github pull requests or to the main newsgroup. So, if you really want folks to see your post and respond, I'd suggest reposting it in the main newsgroup.

- Jonathan M Davis

_______________________________________________
phobos mailing list
phobos@puremagic.com
http://lists.puremagic.com/mailman/listinfo/phobos
August 27, 2015
>> I'm new to this, ....

> The best way to do something like this is to create a pull request. This will not only give you credit for the change and make the code easy to add to Phobos, but it will make sure it doesn’t break any existing tests.
>
> Please have a look here: http://wiki.dlang.org/Pull_Requests <http://wiki.dlang.org/Pull_Requests>
>
> -Steve

Thanks. This is the information I didn't find. Thank you very much.
_______________________________________________
phobos mailing list
phobos@puremagic.com
http://lists.puremagic.com/mailman/listinfo/phobos