On 2/2/07, Adrian Howard <[EMAIL PROTECTED]> wrote:
For example. Module Foo uses objects from module Bar, which uses
objects from module Ni, which uses objects from module Fribble, which
has a exception in a DESTROY block that the author deliberately
doesn't catch because it doesn't signify an error in the code and
they know that exceptions don't propagate out of DESTROY blocks.

There is a different case that needs to be considered.  Module Fribble
uses an eval in it's DESTROY method without error and thus Foo's fatal
error in an eval vanishes.

 eval{ my $foo = Foo->new; die "Fatal Error" };
 like( $@, qr/Fatal Error/, "Caught error");

This will fail (assuming Foo... Bar... Ni... and Fribble as I
described).  As will dies_ok/throws_ok.  Or, put differently, this
will pass:

 lives_ok{ my $foo = Foo->new; die "Fatal Error" };

The DIE handler I posted recently that walks up the caller() stack to
special-case a die in an eval in a DESTROY method could be modified to
do the right thing for Foo, while still not being paranoid about
uncaught exceptions in a DESTROY block somewhere else.

A DIE handler would make sure that $@ would be saved away the very
moment that die() is first called in an eval block (and not in a
DESTROY block),  because it might or might not survive subsequent
calls to DESTROY.

Because Perl normally warns but doesn't die on exceptions in DESTROY,
I would agree that T::E also shouldn't care about such exceptions.

Extending that argument, T::E also shouldn't introduce capabilities
that wouldn't exist for an ordinary programmer using eval {} on
similar code in production.  Consider:

 dies_ok{ my $foo = Foo->new; die "Fatal Error" };
 lives_ok{ my $foo = Foo->new; die "Fatal Error" };

I think a good case should be made that *both* of these should fail if
a DESTROY block with an eval is swallowing up [EMAIL PROTECTED]  A good 
diagnostic
that describes this unexpected result would help programmers realize
that some strange action at a distance is happening.

 not ok 1
 # Code died, but appeared to live because $@ was reset
 # unexpectedly by a DESTROY method called during cleanup
 not ok 2
 # Code died, but appeared to live because $@ was reset
 # unexpectedly by a DESTROY method called during cleanup

Regards,
David

Reply via email to