On Wednesday, 28 May 2014 at 23:27:34 UTC, bearophile wrote:
This is currently accepted code:


void main() {
    import std.array: appender;
    import std.format: formattedWrite;

    auto writer = appender!string;
formattedWrite(writer, "%s is the ultimate %s.", 42, "answer");
    assert(writer.data == "42 is the ultimate answer.");
}



But there are problems caused by formatting for exception error messages:
https://d.puremagic.com/issues/show_bug.cgi?id=12768


An example of the problem:

class UTFException : Exception
{
...
    pure @safe
this(string msg, size_t index, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
        import std.string;
super(msg ~ format(" (at index %s)", index), file, line, next);
    }


Because of that several Phobos functions can't be @nogc.

So is it a good idea to add to Phobos a function similar to this?


void main() pure nothrow @safe @nogc {
    import std.format: bufferText;

    immutable n = 42;
    immutable s = "answer";
    char[100] buf;
    const Nullable!(char[]) result =
        buf.bufferText(n, " is the ultimate ", s);
    assert(result.get == "42 is the ultimate answer.");
}



That should allow (in theory) code like:

class UTFException : Exception
{
...
    pure @safe @nogc
this(in char[] msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
        super(msg, file, line, next);
    }

...

char[100] buf;
const msg = buf.bufferText("Invalid UTF-8 sequence (at index ", i, ')');
if (mgs.isNull)
    new UTFException("Invalid UTF-8 sequence")...
else
    new UTFException(msg.get)...



A problem left is that the ctor of Exception is not yet @pure @nothrow @safe @nogc.

Bye,
bearophile

IMHO something like this is better:

class MyException : Exception
{
private char[20] index_buff; // should be enough for size_t.max

this(string msg, size_t index, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
    {
        super(msg, file, line, next);
        // in-place conversion of size_t to char[]
    }
        
    void toString(void delegate(const(char)[]) sink) const
    {
        sink(msg);
        sink(" (at index ");
        sink(index_buff);
        sink(")");
    }
}

Benefits: no arbitrary message length limit, no string construction unless toString is actually called.

Reply via email to