in reply to Why <c>eval {...};if ($@) { die $@ } else { ...</c> ???

Based on an idiom, I have the following as a template to handle timeouts:
{ local $SIG{__DIE__}; local $@ = ""; eval { local $SIG{ALRM} = sub { die("alarm\n") }; alarm(3); chomp($input = <STDIN>); # potentially long operation alarm(0); 1; } or do { die($@) unless $@ eq "alarm\n"; # timed out warn("No answer for three seconds.\n"); $input = ""; } }

Here, I only want to do_something_more(...) when the alarm is up, but pass on every other $@. So, my if ($@) actually does a little more than your example. Then again, it's subtly different with or do { ... } vs. eval { ... }; if ....

Hope this helps as an example as to why $@ needs to be mucked around :)

Update: Localized $SIG{__DIE__}. Thanks, jplindstrom!</c>

Replies are listed 'Best First'.
Re^2: Why <c>eval {...};if ($@) { die $@ } else { ...</c> ???
by jplindstrom (Monsignor) on Apr 06, 2009 at 14:27 UTC
    Note that anything that happens to alter $SIG{__DIE__} would break that since the exception string wouldn't be "alarm\n" anymore.

    I've done that myself numerous times when adding a use Carp::Always; for debugging purposes, thereby accidentally the whole test run.

    If you want to be extra super safe, you should do local $SIG{__DIE__}; in the block as well.

    /J