in reply to Re: Question on "Effective Perl Programming" (;1 > $@)
in thread Question on "Effective Perl Programming"

Ouch! That will eat any useful exception you want to throw too. Consider:

package EvalEater; sub new { bless {} } sub DESTROY { eval { sleep 1 if 0 } } package main; use Test::More 'tests' => 2; use Exception::Class ( 'Bomb' ); my $okay = eval { my $ee = EvalEater->new(); Bomb->throw( error => 'Ouch!' ); 1; }; ok( ! $@, "Eval appears to succeed: $@" ); ok( ! defined $okay, "Eval failed silently" );

I see the local $@ will fix the EvalEater, but is there a way to rescue the exception if I can't change EvalEater?

Replies are listed 'Best First'.
Re^3: Question on "Effective Perl Programming" (intervene)
by tye (Sage) on Sep 06, 2007 at 14:43 UTC
    package DESTROY::EVAL_ERROR::NOT; my %done; sub import { shift @_; for my $pkg ( @_ ) { next if $done{$pkg}++; $pkg .= "::DESTROY"; my $orig= \&{$pkg}; no warnings; *{$pkg}= sub { local $@; $orig->(@_) }; } }

    Then:

    use Broken::Package; use DESTROY::EVAL_ERROR::NOT qw( Broken::Package ); ...

    In other words, "if I can't change EvalEater" need never be true. :)

    - tye        

      If it takes so much to check that an eval worked, maybe something should be fixed?
        How is this:
        my $worked = eval {stuff}; if ($worked) { print "Yay!"; } else { print "Boo!: $@"; }

        so much to check an eval? That's all you really need to do.