What is the best way to handle exceptions in Perl?
The consensus of the Perl community seems to be that Try::Tiny is the preferred way of doing exception handling. The "lenient policy" you refer to is probably due to a combination of:
- Perl not being a fully object-oriented language. (e.g. in contrast to Java where you can't avoid dealing with exceptions.)
- The background of many Perl developers. (Languages like C1 and shell don't have exception mechanisms.)
- The kind of tasks people tend to use Perl for. (Small scripts for text munging and report generation where exception handling isn't needed.)
- Perl not having a (good) built-in exception mechanism.
Note that the last item means that you'll see a lot of code like this:
eval { something() };
if ($@) {
warn "Oh no! [$@]\n";
}
That's exception handling even though it doesn't use try/catch syntax. It's fragile, though, and will break in a number of subtle edge cases that most people don't think about. Try::Tiny and the other exception handling modules on CPAN were written to make it easier to get right.
1. C does have setjmp()
and longjmp()
, which can be used for a very crude form of exception handling.
Never test $@ as is, because it is a global variable, so even the test itself can change it.
General eval-template:
my $result;
eval {
$result= something();
# ...
1; # ok
} or do {
my $eval_error= $@ || "error";
# ...
die $eval_error;
}; # needs a semicolon
In practice that is the lightest way. It still leaves a tiny room for funny $@ behaviour, but nothing that really concerned me enough.