=head2 eval/die remains perfectly workable
Perl5 has a perfectly agile exception handling method,
C<eval BLOCK>, which syntax-checks at compile time and
returns the value of the value of the last expression
evaluated and sets the special error variables in cases
of errors.
We leave that alone, and use it for all try{} types of
constructions, where we want it explicitly known that a
block of code is running in a padded cell.
reading
perldoc -f die
should be considered required reading (does that do w/out saying?)
as "die" is a perfectly serviceable method or raising an exception.
=head2 THROWING
All (all of them!) errors that will cause a perl program to
end abnormally are internally implemented in terms of a unified
error expression mechanism which can be hooked into by the user
using a C<throw> keyword. This includes syntax errors, in a
well-defined machine-readable format, to be described, if possible.
C<die> takes
==head2 CATCHING
C<eval> protects its BLOCK from exception handlers not declared
within it.
The Entire Program can be considered to be within a big, implicit
C<eval>. C<eval> and analysis of the result remains.
C<catch> is introduced as a keyword that indicates a
handler section.
catch EXPRESSION BLOCK
when an exception is C<throw>n, or a built-in error (which all now have
well defined portable and parseable numbers) occurs, before printing
the message to STDERR and exiting, C<catch> blocks are consulted
regarding would they like to do something with the situation.
Information available in the catch block will include access to the
context the error happened, including well-defined labels indicating
jumping to retrying the block, or blocks previous, after altering
any aspects of the situation.
When called at parsing time, BLOCK is able to rewrite the program in
the error's immediate vicinity.
=head 2 catch selection
each catcher is quereyed via its EXPRESSION re: is it able to
deal with the situation. The order this happens is from the current
block out, in the order that the catches are written into the code,
even if the catches appear after the expression with the error.
The compiler has compiled the catches at compile time, and magically
associates them with the current block in the optree, but in general
they disappear from the flow.
Throwing then becomes another way to implement limited-visibility subroutines,
that extend based on run-time scoping, as well as error trapping.
when an exception does not match any defined C<catch> including the
system ones that produce the default error messages, that's a
no-handler error which starts over from the original error point.
=head2 example
sub openrecord{
my $RecordFileName = &GetRecordFileName;
TRYOPEN:
open REC, "$RecordFileName" or throw "FILE-NO-OPEN";
#work with the file
...
return;
my $problemcounter;
catch "FILE-NO-OPEN"{
$problemcounter++ > 5 and return undef;
$RecordFileName = &GetRecordFileName;
goto TRYOPEN;
};
};
The above is hella cleaner than the same thing done with eval/die;
it could also be done well with file tests and a loop to verify everything
works before attempting the open.
--
David Nicol 816.235.1187 [EMAIL PROTECTED]
Useless use of a void in constant context