Perl - 错误处理

执行和错误总是在一起.如果要打开不存在的文件.然后,如果你没有正确处理这种情况,那么你的程序被认为质量很差.

如果发生错误,程序将停止.因此,正确的错误处理用于处理各种类型的错误,这些错误可能在程序执行期间发生并采取适当的操作,而不是完全停止程序.

您可以识别并捕获错误有许多不同的方式.它很容易在Perl中捕获错误,然后正确处理它们.以下是几种可以使用的方法.

if语句

if语句是你明显的选择需要检查语句的返回值;例如 :

if(open(DATA, $file)) {
   ...
} else {
   die "Error: Couldn't open the file - $!";
}


这里变量$!返回实际的错误消息.或者,我们可以在有意义的情况下将陈述减少到一行;例如 :

open(DATA, $file) || die "Error: Couldn't open the file $!";


除非函数

除非函数与if:语句的逻辑相反可以完全绕过成功状态,只有在表达式返回false时才会执行.例如 :

unless(chdir("/etc")) {
   die "Error: Can't change directory - $!";
}


除非语句最适合用于仅在表达式失败时引发错误或替代错误的情况.当在单行语句中使用时该语句也有意义 :

die "Error: Can't change directory!: $!" unless(chdir("/etc"));


这里我们只有在chdir操作失败时才会死掉,并且它读得很好.

三元运算符

对于非常短的测试,您可以使用条件运算符?:

print(exists($hash{value}) ? 'There' : 'Missing',"\n");


这里我们想要达到的目标并不是那么清楚,但效果与使用 if

警告函数

警告函数只是发出警告,消息打印到STDERR,但不采取进一步的操作.因此,如果您只想为用户打印警告并继续执行其余操作并减去它,则更有用;

chdir('/etc') or warn "Can't change directory";


模具功能

模具功能就像警告一样工作,除了它还调用退出.在普通脚本中,此函数具有立即终止执行的效果.你应该使用这个函数以防万一程序中出现错误并且没有用;

chdir('/etc') or die "Can't change directory";


模块内的错误

我们应该能够处理两种不同的情况 :

  • 在引用模块文件名和行号的模块中报告错误 - 这在调试模块或特别想要时很有用引发与模块相关的错误,而不是与脚本相关的错误.

  • 报告模块中引用调用者信息的错误,以便您可以调试该行在导致错误的脚本中.以这种方式引发的错误对最终用户很有用,因为它们突出显示与调用脚本的原始行相关的错误.

warn die 函数的工作方式与模块中调用时的工作方式略有不同.例如,简单模块 :

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   warn "Error in module!";
}
1;


从下面和下面的脚本调用时;

use T;
function();


它将产生以下结果 :

Error in module! at T.pm line 9.


这或多或少是你所期望的,但不一定是你想要的.从模块程序员的角度来看,这些信息非常有用,因为它有助于指出模块本身的错误.对于最终用户来说,提供的信息是相当无用的,除了强化的程序员之外,它完全没有意义.

这些问题的解决方案是Carp模块,它提供了一个报告模块内错误的简化方法,返回有关调用脚本的信息.鲤鱼模块提供四种功能:鲤鱼,咯咯,呱呱声和忏悔.这些函数将在下面讨论.

carp函数

carp函数是warn的基本等价物,并将消息打印到STDERR而不实际退出脚本和打印脚本名称.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   carp "Error in module!";
}
1;


从下面和下面的脚本调用时;

use T;
function();


它将产生以下结果 :

Error in module! at test.pl line 4


cluck函数

cluck函数是一种增压鲤鱼,它遵循相同的基本原则,但也打印导致被调用函数的所有模块的堆栈跟踪,包括原始脚本的信息.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp qw(cluck);

sub function {
   cluck "Error in module!";
}
1;


从下面和下面的脚本调用时;

use T;
function();


它将产生以下结果 :

Error in module! at T.pm line 9
   T::function() called at test.pl line 4


croak函数

croak 函数相当于 die ,除了它将调用者报告一级.与die一样,此函数在将错误报告给STDERR&minus后退出脚本;

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   croak "Error in module!";
}
1;


从下面和下面的脚本调用时;

use T;
function();


它将产生以下结果 :

Error in module! at test.pl line 4


与carp一样,根据warn和die函数,包含行和文件信息的相同基本规则也适用.

confess函数

confess

函数confess就像 cluck ;它调用die然后打印堆栈跟踪一直到原始脚本.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   confess "Error in module!";
}
1;


从下面和下面的脚本调用时;

use T;
function();


它将产生以下结果 :

Error in module! at T.pm line 9
   T::function() called at test.pl line 4