I'm not sure bounding in like a bungee boss and saying "I'm here to challenge the status quo! The prevailing wisdom doesn't always work!" is the way to do that, which is why I responded to BrowserUk so strongly.

Unfortunately, as is so often the case, you were so busy responding strongly, that you either: a) didn't bother to read what I wrote; or b) read it, and decided that it was easier (or perhaps, more entertaining) to take minutia of my posts and blow them out of proportion, than to deal with the argument itself.

For example. Read back and you'll find that string eval was just supporting example to a wider point--accusation if you prefer--that, despite recognising the importance of test code, by using the Test::* modules to create test suites, you I the Test::* user is forced to apply different standards to the code in their test suite than they would apply, (and you would advocate), for their production code.

I do not have a problem with the use of string eval--subject to sensible precations. As I've pointed out before, and I seem to recall but cannot find, you may have done similar, when you get down to base level, all Perl code is handled through string eval: use is require is do is eval. Only two things differ. The source of the string and the timing of the evaluation.

Indeed, I've spoken up against the unthinking paranoia--"if you cannot trust the source of the code it can be dangerous; if you repeatedly evaluate the same code, it can be slow"--that surrounds string eval, being converted into "string eval is evil", on many occasions in this place. Provided the code being evaluated originates from within your own filesystem/organisation, and is provenanced with the same credentials, there is no greater risk between evaluating that code at runtime, and evaluating a perl source file at compile time.

And provided that you do not evaluate identical code more than once, (think Memoize or a hash lookup), then it is no slower than doing the same thing at compile time. And far faster than trying to replicate the Perl parser using Perl code (C vs. Perl) or (for example) Parser::RecDescent.

And it is this last point that I was making about Test::Builder's use of string eval. If you are, at the lowest level, going to kick the responsibility of performing a comparison test off to Perl's parser (via string eval), why bother with interspersing all the layers between those comparisons and the Perl parser? You mentioned that you had attempted a dispatch table solution but that string eval proved to be faster. You also challenged me (though I'm pretty sure it was more of a dare than a challenge), to suggest an alternative that would deal with all the edge cases and caveats that had been evolved into T::B. Well, here is an idea for you: Let Perl do it

How? How about this? (And I know before posting that you will find a reason for not using it (based upon my crude implementation. Perhaps something to do with supporting ancient builds?):

package Assert; require Exporter; our @ISA = 'Exporter'; our @EXPORT = qw[ assertOk assert ]; my $nTests = 0; sub assertOk (&$;) { my( $package, $file, $line ) = caller; my( $code, $desc ) = @_; warn sprintf "%s %d # %s [%s(%d)]\n", ( $code->() ? 'ok' : 'not ok' ), ++$nTests, $desc, $file, $line ; } 1;

To produce:

#! perl -slw use strict; use Assert; my $fred = 1; assertOk { $fred eq 'fred' } 'Check $fred'; assertOk { 2 == 1 } 'Check math'; $fred = 'fred'; assertOk { $fred eq 'fred' } 'Check $fred'; assertOk { 2 == 2 } 'Check math'; __END__ [ 3:14:54.52]C:\test>t-Assert.pl not ok 1 # Check $fred [C:\test\t-Assert.pl(7)] not ok 2 # Check math [C:\test\t-Assert.pl(8)] ok 3 # Check $fred [C:\test\t-Assert.pl(12)] ok 4 # Check math [C:\test\t-Assert.pl(13)]

As far as I am able to discern, as the code will be run with the context of the calling code, the interpretation of any variables--be they tied, overloaded or whatever--should be identical to the way they would be interpreted if executed at the same point in the calling code. Assuming that you arrive at similar conclusions, no doubt you'll let me know if not, then go back and look at the shenanigans that similar code goes through before being passed back to string eval. And also consider the less than stellar syntax that it requires.

One possible objection to this is that it cannot (easily; ignoring B::* for the moment), automatically produce a comment that shows the exact code. I have two answers to that:

  1. if you gave me the file/lineno (as shown above) in a 'standard' form--inline with the failure notification, rather than spread across a variable number of lines as currently--then when I run the test from within my editor, I can have it parse the results and take me directly to the failing line of code. This is far more useful than printing it in the output, as it is in context and is editable.
  2. If you look at what Smart::Comments, you'll see that it achieves listing the actual failing code. Of course, it is a source filter and so (in some circles) verbotten. But is it really worse than string eval?

But my primary objections to Test::*, are:

I do not expect a meaningful response to this, because that would require you to actually consider my arguments rather than using spoiling tactics, like exploiting a typo , to dismiss them.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

In reply to Re^4: "Practices and Principles" to death by BrowserUk
in thread "Practices and Principles" to death by ack

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.