How To Look Like An Idiot

Ovid on 2008-07-15T10:36:08

So I bitterly complain about people globally changing things that has the side-effect of breaking my code. Some changes are well-intentioned, but even those often break my code. If you ack through your @INC, you'll often find all sorts of CORE::GLOBAL trickery which just doesn't belong there. Which is why my post yesterday on customizing Test::Most is a wee bit embarrassing.

Oh, it looks safe enough, but there's this little bit here:

for my $i ( 0 .. $#_ ) {
    if ( 'trace' eq ( $_[$i] || '' ) ) {
        splice @_, $i, 1;
        $SIG{__DIE__} = sub {
            require Carp;
            Carp::confess(@_);
        };
    }
}

That let's me do use Pips3::Test::Most qw/no_plan trace/; and get a stack trace when a test fails. Nifty, eh? Plus, it only overrides $SIG{__DIE__} when I ask for it. Er, sort of.

I spent a lot of time debugging some tests running under Test::Aggregate. Our tests run about three times faster under that, but were somehow failing miserably for mysterious reasons. Seems that when a test with "trace" enabled was aggregated, other tests in different files picked up the trace and exception tests would often fail mysteriously. I'm uploading a new version of Test::Aggregate to PAUSE which ensures that the TEST_AGGREGATE environment variable is set in a BEGIN block (as it should have been). This allows me to do this:

for my $i ( 0 .. $#_ ) {
    if ( 'trace' eq ( $_[$i] || '' ) ) {
        splice @_, $i, 1;
        if ( $ENV{TEST_AGGREGATE} ) {
            explain("No tracing aggregate tests (due to tests checking exceptions");
        }
        else {
            $SIG{__DIE__} = sub {
                require Carp;
                Carp::confess(@_);
            };
        }
    }
}

I'll think of a better fix later, but for right now, this will do.

Once again, a global change to behavior, no matter how safely written, breaks things in strange and mysterious ways.