Документация
HTML CSS PHP PERL другое

Section 2.2.  Trapping Errors with eval

 
Previous
Table of Contents
Next

2.2. Trapping Errors with eval

Many lines of ordinary code have the potential to terminate a program prematurely if something goes wrong.

my $average = $total / $count;                # divide by zero?
print "okay\n" unless /$match/;                # illegal pattern?

open MINNOW, '>ship.txt'
or die "Can't create 'ship.txt': $!";        # user-defined die?

&implement($_) foreach @rescue_scheme;        # die inside sub?

But just because something has gone wrong with one part of our code, that doesn't mean that we want everything to crash. Perl uses the eval operator as its error-trapping mechanism.

eval { $average = $total / $count } ;

If an error happens while running code inside an eval block, the block is done executing. But even though the code inside the block is finished, Perl continues running the code just after the eval. It's most common after an eval to immediately check $@, which will either be empty (meaning that there was no error) or the dying words Perl had from the code that failed, perhaps something like "divide by zero" or a longer error message.

eval { $average = $total / $count } ;
print "Continuing after error: $@" if $@;

eval { &rescue_scheme_42 } ;
print "Continuing after error: $@" if $@;

The semicolon is needed after the eval block because eval is a function (not a control structure, such as if or while). But the block is a true block and may include lexical variables ("my" variables) and any other arbitrary statements. As a function, eval has a return value much like a subroutine's (the last expression evaluated, or a value returned early by the return keyword). Of course, if the code in the block fails, no value is returned; this gives undef in a scalar context, or an empty list in a list context. Thus, another way to calculate an average safely looks like this:

my $average = eval { $total / $count } ;

Now $average is either the quotient or undef, depending upon whether the operation completed successfully or not.

Perl even supports nested eval blocks. The power of an eval block to trap errors extends for as long as it's executing, so it catches errors deep within nested subroutine calls. eval can't trap the most serious of errors, though: the ones in which Perl itself stops running. These include things such as an uncaught signal, running out of memory, and other catastrophes. eval doesn't catch syntax errors , either; because Perl compiles the eval block with the rest of the code, it catches syntax errors at compile time, not at runtime. It doesn't catch warnings either (although Perl does provide a way to intercept warning messages; see $SIG{_ _WARN_ _}).


Previous
Table of Contents
Next
© 2000- NIV