On Sat, Feb 12, 2005 at 11:30:56PM -0500, David A. Golden wrote:
> > stdout_is {
> > print scalar caller;
> > } scalar caller;
>
> That's a good warning on code blocks, and worth documenting for a module
> like this, but I'm not sure it's going to be a big issue in writing test
> scripts. Unless you're testing the "print" built-in function, that test
> is more easily written as
>
> is(scalar caller, scalar caller)
Carp. Stack traces. Testing functions. Error messages. Anything which
makes use of caller can have its results altered. The above was just the
simplest possible illustration of the problem. Here's a slightly more
pragmatic example.
#!/usr/bin/perl
use Carp;
sub test (&) { $_[0]->() }
sub foo { carp "In foo" }
#line 10
test { foo() };
#line 10
foo();
__END__
In foo at /Users/schwern/tmp/stack.plx line 7
main::foo() called at /Users/schwern/tmp/stack.plx line 10
main::__ANON__() called at /Users/schwern/tmp/stack.plx line 5
main::test('CODE(0x809f6c)') called at /Users/schwern/tmp/stack.plx
line 10
In foo at /Users/schwern/tmp/stack.plx line 7
main::foo() called at /Users/schwern/tmp/stack.plx line 10
The result of those two calls to foo() should be exactly the same, the
testing function should not interfere at all otherwise you have the test
altering the environment and adding another variable to testing a bug.
Its rare but when it happens it can cause hours of frustration when the
test is performing differently than the regular code.
The simplest way to avoid this is to use Sub::Uplevel. Or don't try to
force the (&) prototype into being a block. This is another reason I
prefer ->read().