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 $!";
    
  • unless 函数

    unless 函数是逻辑相反,语句可以完全绕过成功状态且仅当表达式为假来执行。例如-
    
    unless(chdir("/etc")) {
       die "Error: Can't change directory - $!";
    }
    
    unless 是当你想抛出一个错误或者替代只有表达式失败语句是最好的使用。该语句在单行语句中使用时也很有意义-
    
    die "Error: Can't change directory!: $!" unless(chdir("/etc"));
    
    在这里,仅当chdir操作失败并且它读取良好时,我们才会只想die。
  • 三元运算符

    对于非常简短的测试,可以使用条件运算符?:
    
    print(exists($hash{value}) ? 'There' : 'Missing',"\n");
    
    此处我们要实现的目标还不是很清楚,但是效果与使用if或else语句相同。当您要快速返回表达式或语句中的两个值之一时,最好使用条件运算符。
  • warn 函数

    warn 函数仅会发出警告,一条消息会打印到STDERR,但不会采取进一步措施。因此,如果您只想为用户打印警告并继续进行其余操作,它会更有用-
    
    chdir('/etc') or warn "Can't change directory";
    
  • die 函数

    die 函数的作用与 warn 相似,只是它还会调用 exit。在普通脚本中,此函数具有立即终止执行的作用。如果程序中有错误,则应使用此功能以防继续进行-
    
    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, cluck, croak, 和 confess。这些功能将在下面讨论。
  • 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函数是一种 carp 函数 的加强版,它遵循相同的基本原理,但还会打印导致该函数被调用的所有模块的堆栈跟踪,包括原始脚本中的信息。
    
    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报告错误后退出脚本-
    
    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 函数就像是 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