Program scripts in the process of running, always encounter such a problem, we will anticipate some problems and prepare them for processing code, and some unpredictable. The good program should be able to deal with as many of the possible anomalies as possible, this article summarizes some methods to solve these anomalies, of course, Perl in this processing than other similar languages, but it will not be poor there. Before we start, let's take a stock of some of the advantages and disadvantages of Perl.
0. History is too long. You can find perl5.0 on a computer in 1997. (Just spit a bit, the history of a long time is not bad, the Times is the key)
1. Do not recycle garbage (this is a mishap, perhaps with the original intention of the Perl design, small script has little impact; but because of this, Perl and a slightly larger program will be missed)
2. Fault tolerance (such as implicit conversion of strings and numeric values, etc.), but in other words it is too indulgent for errors, and the program produces incorrect results rather than errors.
3. There are many ways to do something (TIMTOWTDY), but in other words there is no "one obvious way" to do something. For example, the length of the array is $ #somearray +1. Why is it a plus? Isn't it somearray.length or Len (somearray)?
4. Grammar is more difficult to understand. The syntax is also located on the "scripting language" (referring to a batch script that is readily discarded), just a bit more like a traditional programming language than a shell script. Like what:
4.1 uses the $ symbol extensively, as well as various special variables represented by symbols.
The 4.2 function does not take a formal parameter list.
4.3 Object-oriented support bad: There is no object syntax in the syntax (no keywords such as Class), all by hash and bless. Inheritance relies on Isa, and there is no syntax support.
4.4 Only basic exception handling (Perl eval and Die, Java-like try and throw). But exceptions are just a string of information, with less object-based exception systems, and exception handling is always inferior to other languages.
All of these can affect readability and legibility. It is important to note that the human brain can also focus on the information is limited. If you write business logic, but have to constantly focus on implementation details (such as the use of package, hash, ISA, bless to achieve object-oriented), the programmer's ideas will continue to be disrupted by these details, dramatically reduce programming speed, but also constantly make mistakes, even for the sake of simplicity and sacrifice efficiency or even correctness.
A high-level language is an abstraction of a high-level concept that allows programmers to detach their mind from the details of the underlying (separation of Concern). Perl as a scripting language for batch text is enough to do a lot of string processing that the shell is not good at (regular expressions are great) and calculations, which is good at the time. But for a slightly larger program, even if you need to object-oriented, Perl is not appropriate.
Perl can write very short code (Google a bit "code Golf"), at which Ruby is more like Perl. Here are some tips for getting Perl scripts to be more prescriptive and even better handled when errors occur.
turn on constraint directives to make coding more canonical
If you use perl5.10 or a higher version, you can display the specified current Perl version number to automatically open the constraint directive.
Use 5.012; #自动启用use Strict instructions
Use v5.10; #自动布严格模式
The previous version was added by adding the following directives:
Use strict;
By enabling constraint directives, common errors in programming are easily exposed. If you enable the warnings directive, you can catch some other issues that are not very critical.
If you are concerned that the program is not working properly after you have enabled strict, you can try to enable strict on the command line before actually modifying the code:
Perl-mstrict freeoa_program.pl
The constraints set for Perl include VARs (variables), subs (subroutines), and refs (reference), which are typically used by these three constraints.
In many cases, system calls may fail, such as attempting to open a nonexistent file, or deleting a directory that still contains files, or attempting to read a file that does not have read permissions. In the previous example, we have used the die function to discuss the error handling and error handling functions in detail. These functions include the die function, the Warn function, and the Eval function.
The die function is used to exit a Perl script when a command or file handle fails.
The Warn function is similar to the die function, but it does not exit the script.
The Eval function has many uses, but it is mostly used for exception handling.
The reader must remember the short-circuit operator && and | |, the two operators first seek the value of their left operand before the value of its right operand is evaluated. If the && left action value is true, the operand to the right is asked. if | | The value of the left operand is false, which is the number of operands to the right.
The Carp module provided by Perl 5 extends the functionality of die and warn
If there is an exception in a piece of code, but you do not know in advance which sentence, how to catch the exception?
eval{, ...}; #捕获运行时的错误
if ([email protected]) {...}; #进行错误处理
Using the eval statement from Perl to parse the error and use the standard method to handle Perl errors, use the following syntax:
eval {Enter statements want to monitor};
At run time, if the Perl engine encounters an error in the statement within the Eval block, it skips over the remainder of the eval block and sets [email protected] for the corresponding error text. For example:
eval{$objectName->methodname ();};
if ([email protected]) {
Print "Error using MethodName method. Error: [email protected]\n];
}
else{
# Continue without error ...
}
Some functions that are expected to fail normally are not included in this range. In particular, validation and setting of field functions return error descriptions, rather than throwing exceptions. This intercepts the internal interrupt signal and processes it, rather than simply letting the program handle the exception by default.
The recommended-some things, like timeouts, was through an eval/die pair. However, I ' ve noticed so if you set $SIG {__die__} to does some custom reporting, like in:
$SIG {__warn__} = sub {...}; # Custom Error Report
$SIG {__die__} = sub {&{$SIG {__warn__}; exit (1);};
# Custom error report and terminate
eval {
$SIG {ALRM} = sub {die "timeout\n";};
Alarm 20;
...
Alarm 0;
}
"Die" isn ' t caught! It remains fatal!
The only-to-around this (that I-found), is-to-clear $SIG {__die__} in the Eval blok:
eval{
Local ($SIG {__die__}); #back to Standard Perl die
...
}
Question:is there another A-terminate a __die__ sub, that's not fatal in eval? "Die" doesn ' t die in Eval, but only if you didn ' t set $SIG {__die__} yourself (even outside of the eval block). Surely, this can ' t be the The IT's supposed to be?
You'd better use the Try::tiny module to handle these problems, which will help you avoid pitfalls in some old versions.
Use Try::tiny;
try{
Die "Foo";
}catch{
Warn "Caught error: $_";
};
Sometimes we often write multiple open, and then write more than one die like below, read a file, and then write a file, sometimes I write more than 4 open, to write many times it is very troublesome. If we use Autodie directly to solve all the problems, all die can be automatically realized.
Open my $fh, ' < ', $in or Die "$!";
Open my $fh, ' > ', $out or Die "$!";
Simplifying error handling with Autodie
Autodie compilation instructions (from 5.10.1 onwards, can also be installed directly from the CPAN)
By default, Autodie will take effect for all functions that it can work on. If you just want to work on certain functions, you can name the names of individual functions or groups of functions to tell Autodie:
Use Autodie QW (open close); #只对特定函数生效
Use Autodie QW (: Filesys); #只对 a set of functions to take effect
When Autodie catches an error, it sets [email protected] to autodie::exception object, and [email protected] is the eval error variable
Plus Autodie.
Use Autodie
Open my $fh, ' < ', $fin;
Open my $fh, ' > ', $fout;
With this convenience, sometimes we often do not want to let the program die back out, want to catch the reason, you have to use Eval and then to check [email protected], like the following.
Use Autodie;
eval{
Open my $fh, ' < ', $in;
# .....
}
if ([email protected]) {
#TODO
}
eval{
Open my $fh, ' > ', $out;
}
if ([email protected]) {
#TODO
}
Fortunately last time only two open. is not feeling very painful, if open and so will die of more points. In addition, there is no discovery, as long as the first open failed, the second if ([email protected]) will never fail, because [email protected] under the tag also check the same variables. Then use the Try catch in Try::tiny.
Use with the Try::tiny module
Perl does not have a built-in exception handling mechanism, so the most appropriate method is to use the Try::tiny module. Although there are many modules dealing with exceptions in CPAN, this module is the most lightweight and does not have much dependency on it.
Use Autodie;
Use Try::tiny;
# Handle errors with a catch handler
try{
Die "Foo";
}catch{
Warn "Caught error: $_"; # not [email protected]
};
Note: The catch code ends with a semicolon and is an expression. In addition, it will save the error information in the variable $_ instead of [email protected].
It is convenient to use at this time
Use Autodie;
Use Try::tiny;
try {
Open my $fh, ' < ', $in;
# .....
Open my $fh, ' > ', $out;
# .....
}
catch {
Print "Error $_\n";
}
Sometimes we can also use ' Try Catch ' in this place to do program flow control
Use Autodie;
Use Try::tiny;
try {
&sub1 ();
&SUB2 ();
&sub3 ();
}
catch {
&suba ();
&subb ();
&SUBC ();
}
Like above, as long as in Sub1, SUB2, sub3 any one of the sub-function die out, this process is considered to be wrong, do other other scenarios of the process SUBA,SUBB,SUBC.
Summary of "reprint" Perl exception handling method