How to use eval for exception handling in Perl?
Question
How to use eval for exception handling in Perl?
In Perl, eval is a built-in function commonly used for exception handling. It allows you to catch runtime errors and continue program execution gracefully instead of crashing your script.
There are two forms of eval in Perl: eval BLOCK and eval STRING. For exception handling, the block form (eval { ... }) is preferred because it is safer and more efficient.
How eval works for exception handling
- The code inside an
evalblock is executed in a protected environment. - If a runtime error (such as
die) occurs within the block,evaltraps it and puts the error message into the special variable$@. - Your script can then test
$@to determine if an error occurred and respond accordingly. - If no errors occur,
$@is cleared (set to the empty string).
Basic example of eval for exception handling
#!/usr/bin/perl
use strict;
use warnings;
# This subroutine will throw an exception (die) if input is negative
sub check_positive {
my ($num) = @_;
die "Negative number: $num\n" if $num < 0;
return "Number $num is positive";
}
my @nums = (10, 5, -1, 7);
foreach my $n (@nums) {
my $result = eval {
# Protected code block
check_positive($n);
};
if ($@) {
# $@ contains the error from die
print "Caught error for input $n: $@";
} else {
print "Success: $result\n";
}
}
When you run this code, it will output:
Success: Number 10 is positive
Success: Number 5 is positive
Caught error for input -1: Negative number: -1
Success: Number 7 is positive
Important Perl-specific details
- Sigils:
$@is a scalar variable that holds the error message string from the lasteval. - Context: The
evalblock returns the last evaluated expression in scalar or list context. You can capture that return value to handle success cases. - TMTOWTDI: Perl allows various ways to handle exceptions, including using
eval, modules likeTry::Tiny, or object-oriented exception handling. Butevalremains the classic and core way to catch errors.
Common pitfalls and gotchas
$@is global and can be overwritten. Always check it immediately afterevalbefore running other code.- A common mistake is forgetting to localize
$@if your code might be running inside otherevalblocks. Uselocal $@to avoid clobbering errors. eval STRINGevaluates a string as code at runtime. This is slower, potentially unsafe, and not recommended for exception handling.- While
evalcatchesdieexceptions and runtime errors, it does not catch syntax errors occurring before runtime.
Summary
Using eval { ... } is the canonical way to add exception handling in Perl. Wrap potentially error-throwing code inside eval, then check $@ for errors. This approach enables safe, controlled error handling without stopping your entire program abruptly.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 7ms
Success: Number 10 is positive
Success: Number 5 is positive
Caught error for input -1: Negative number: -1
Success: Number 7 is positive
(empty)