[phobos] Changing the semantics of std.string.format

Lars Tandle Kyllingstad lars at kyllingen.net
Thu Mar 3 00:53:07 PST 2011


I've looked into issue 5687, 'std.string.format() error with "%a"'.

    http://d.puremagic.com/issues/show_bug.cgi?id=5687

In short, the problem is that format() calls std.format.doFormat(),
which converts all floating-point numbers internally to 80-bit reals.
For "%a", this is most definitely *not* what you want.

I think it will be a hassle to fix doFormat(), and it looks to me as
though it's headed for deprecation anyway, being replaced by
formattedWrite().

I say the way to go is to rewrite format() in terms of formattedWrite(),
like this:

    string format(String, Args...)(String fmt, Args args)
        if (isSomeString!String)
    {
        auto app = appender!string();
        formattedWrite(app, fmt, args);
        return app.data;
    }

This is nice and simple, and it will make format() consistent with
writefln().  The problem is that it is a breaking change.

The biggest problem is the following, because it won't be caught at
compile time and produces subtly different results at run time.

    // before
    assert (format("%s", 123, 456) == "123456");

    // after
    assert (format("%s", 123, 456) == "123");

The following currently works, but won't compile after the change:

    assert (format(123, " %a", 1.0) == "123 0x8p-3");
    assert (format(123, 456) == "123456");

I don't really think these two are a problem, though, because the first
one is rather obscure, while the second case is now taken care of by
std.conv.text().

Does anyone object to me making this change to format()?

-Lars






More information about the phobos mailing list