Is it possible to obtain textual representation of an arbitary code?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Jan 26 14:44:34 UTC 2018


On Friday, January 26, 2018 14:23:20 Oleksii Skidan via Digitalmars-d-learn 
wrote:
> On Friday, 26 January 2018 at 13:05:26 UTC, Jonathan M Davis
>
> wrote:
> > Why are you using strings for any of this? Printing out the
> > expression is kind of pointless. If you have the file and line
> > number (which an AssertError will give you), then you know
> > where the failure is, and you can see the expression. All of
> > this extra machinery is just going to increase your compile
> > times for no benefit. So, what you're doing here is objectively
> > worse than just using assertions.
> >
> > There might be some value if you had something like
> >
> > assertEqual(lhs, rhs);
> >
> > and then on failure, you printed the values that were being
> > compared, since that's not necessarily information that's in
> > the code, but the expressions themselves _are_ already in the
> > code, so printing them out doesn't help any.
>
> That's actually what I have:
>
> ```
> // Usage:
> //  mixin(requireEq!q{expected, actual});
> // Checks whether the `actual` value is equal to `reauired`.
> string requireEq(string expr)(string file = __FILE__, int line =
> __LINE__)
> {
>      import std.array, std.conv, std.string;
>
>      auto parts = expr.split(",");
>
>      return q{
>          {
>              bool equal = false;
>
>              static if (__traits(isFloating, $expected) ||
> __traits(isFloating, $actual)) {
>                  import std.math;
>                  equal = approxEqual($expected, $actual);
>              } else {
>                  equal = $expected == $actual;
>              }
>
>              if (!equal) {
>                  import std.stdio, std.conv;
>                  writeln("Test failed @", `$file`, ":", $line,
> "\n",
>                          "  Expected `", `$actual`, "` to be `",
> to!string($expected), "`, but got `",
>
> to!string($actual), "`\n");
>              }
>          }
>      }.replace("$expected", parts[0].strip())
>       .replace("$actual",   parts[1].strip())
>       .replace("$file",     file)
>       .replace("$line",     to!string(line));
> }
>
> ```
>
> The sample code I posted before, was way much simpler than this.

If that's what you want, there's still no reason to use strings. Just take
the two arguments separately as normal function arguments and print their
values when there's a failure. Why are you using strings and mixins for any
of this? You could do something like

void assertEqual(T, U)(T lhs, U rhs, string file = __FILE__,
                       size_t line = __LINE__)
{
    enforce!AssertError(lhs == rhs,
                        format("assertEqual failed. lhs: %s, rhs: %s",
                               lhs, rhs),
                        file, line);
}

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list