More Bugs Due to Global Changes

Ovid on 2008-02-12T15:18:29

Damn. I accepted a patch for aliased to have proper $SIG{__DIE__} handling, but it turned out to have a bug. I have to accept responsibility for this one since it is my module.

use Test::More tests => 1;
use aliased 'CGI';  # doesn't matter which module you use
ok 1, 'dummy test';
Foo->bar;
__END__
nofail......
1..1
ok 1 - dummy test
Can't locate object method "bar" via package "Foo" (perhaps you forgot to load "Foo"?) at nofail.t line 504.
ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.01 usr  0.00 sys +  0.21 cusr  0.01 csys =  0.23 CPU)
Result: PASS

This fails because Test::Builder has its own $SIG{__DIE__} handler and it checks to see if it's in an eval. If not, it sets Test_Died to true. When we get to Foo->bar, Test::Builder's $SIG{__DIE__} handler is wiped out and it can't tell itself that the test died. I hope to have a new version up shortly.

In other words, we once again have a problem with writing code with a global effect. I don't know how this one could be avoided in Test::Builder, but aliased clearly had this wrong.

In this case, the intent of the $SIG{__DIE__} handling code in aliased was not to alter anything about the handlers, but to preserve their semantics just as if you hadn't used aliased. This now brings me up to four modules which have caused various bugs or performance hits here because of global effects. This is not the largest code base I've worked on, but I'm surprised that we're having a much larger problem than I've seen in others.