perlexceptionevaldie

Why do I need to localize $@ before using eval?


I'm aware of the fact that $@ is a global variable, still I can't figure out why I need to localize it before using eval:

For instance:

eval { SOME_FUNC_THAT_MAY_DIE(); };
if ($@) {
  print "An error occured!\n";
}

The only possible thing I can think of is, if some signal handler will call die at the same time I try to read $@, what am I missing here?


Solution

  • The reason to say local $@ before calling eval is to avoid stepping on your caller's $@. It's rude for a subroutine to alter any global variables (unless that's one of the stated purposes of the subroutine). This isn't really an issue with top-level code (not inside any subroutine).

    Also, on older Perl's, any eval called during object destruction would clobber the global $@ (if the object was being destroyed because an exception was being thrown from an eval block) unless $@ was localized first. This was fixed in 5.14.0, but many people are still running older Perls.