Real opIndex(size_t row, size_t col = 0) const pure nothrow {
assert(col + row * Col < Row * Col, "index out of bounds.");
return _data[col + row * Col];
}
Today this assertion failed, and I wanted to see the actual values of row
and col
. Unfortunetly, assert
isn't like writeln
or writefln
, so I can't do something like:
assert(col + row * Col < Row * Col, "index out of bounds. row: %d col: %d", row, col);
I even tried this:
assert(col + row * Col < Row * Col, "index out of bounds" ~ to!string(row)~ " " ~ to!string(col));
But I can't call to
because opIndex
is pure. I could temporarily remove pure
from opIndex
, but that triggers a long chain of undos because other pure methods are calling opIndex
. Not being able to call to
also eliminates the possibility of creating my own function to pass to assert
.
So, What else is there to try? I just want to print such values when assertion fails.
For the moment, if you want to convert to or from strings in a pure
function, you're going to have to write the conversion functions yourself. Some work has gone into making functions like std.conv.to
pure
, but we haven't yet reached the point where they are. Too many lower level constructs still aren't pure
, even if they theoretically could be. A lot of work is being put into making stuff const
-correct for the next release of dmd (2.059), and some work on pure
goes hand-in-hand with that, since certain functions in Object
are going to have to be pure
, const
, @safe
, and nothrow
. So, there's a good chance that std.conv.to
will be able to be pure
for converting to and from strings with the next release. And even if it doesn't happen with the next release, it's going to happen soon, since it does need to happen (as your predicament illustrates). But until then, you're on your own.
Assuming that all of that was sorted out, then the best way to create a string for your assertion would be
assert(col + row * col < row * col,
format("index out of bounds. row: %d col: %d", row, col));
which will work in a impure function, but until format
can be pure
, it won't work in a pure
one.
Now, you can put impure stuff in a debug
block. So, if you wanted to, you could do
debug
{
assert(col + row * col < row * col,
format("index out of bounds. row: %d col: %d", row, col));
}
but then you'd have to compile with -debug
or your assertion wouldn't be run. But regardless, debug
will allow you to put impure code in your your pure
function for debugging purposes and will be compiled in as long as the -debug
flag is used, so it can serve as a temporary workaround for the current deficiencies of format
and to
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With