in reply to Re: Rethrowing with die $@ considered harmful
in thread Rethrowing with die $@ considered harmful

I would consider inadvertently clearing $@ (or $!) as harmful, not the rethrowing.

But there are so many places where this can happen.

eval { foo() } ; if ( $@ ) { bar(); die $@ }

Does bar() throw an exception itself? If it doesn't now will it sometime in the future? What about the stuff that bar() calls? What about the next version of the module Foo used by module Bar used by the bar() function?

If you rely on $@ you're relying on everything in your exception handling code restoring it before you use it. Me - I'll copy it instead. Coupling bad.

Sure the overloading thing is daft - but that doesn't mean copying $@ isn't the right thing to do.

Replies are listed 'Best First'.
Re^3: Rethrowing with die $@ considered harmful
by shmem (Chancellor) on Jul 18, 2006 at 08:21 UTC
    I consider this code buggy. If $@ is set, it must be reported/processed immediately without any further function call. If you just can't die from it, use warn:
    eval { foo() } ; if ( $@ ) { warn $@; bar(); } Undefined subroutine &main::foo called at 561955.pl line 2. Undefined subroutine &main::bar called at 561955.pl line 5.

    Note: I'm not against copying $@. If you need to make further calls first, copy it and report it later. But inadvertently clearing is a programmer's bug, not perl's fault.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
    200th post
      I consider this code buggy. If $@ is set, it must be reported/processed immediately without any further function call.

      I agree. That was my (and I believe the OPs) point!

Re^3: Rethrowing with die $@ considered harmful
by xdg (Monsignor) on Jul 18, 2006 at 11:25 UTC
    Does bar() throw an exception itself?

    Getting away from working with $@ directly is one reason why I wrote Exception::Class::TryCatch -- the try keyword on eval isn't just sugar, it saves away $@ onto a stack for a later catch. That way, it can even be nested. E.g.

    use Exception::Class::TryCatch; try eval { Exception::Class::Base->throw('error') }; # can eval or use try/catch again regardless of $@ above bar(); catch my $err; # catches the matching "try"

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.