Perl编译器可以告诉我我的代码中是否有未经检查的异常吗?

时间:2010-04-28 07:11:03

标签: perl exception compiler-construction die

在Perl中是否有办法声明方法可以抛出错误(或死掉)?

编辑:最让我感兴趣的是让编译器或IDE告诉我我的代码中有某个未经检查的异常的方法。

我一直很喜欢在Java中,一个方法可以处理异常和/或抛出它。方法签名允许放置“抛出MyException”,因此一个好的IDE /编译器会知道如果你在代码中的某个地方使用所述方法,你必须检查Exception或声明你的函数以“进一步”抛出异常

我无法在Perl中找到类似的东西。我的一个同事写了一个方法,在错误的输入上“死”,但是我忘了eval-if($ @)它...当然只有在用户运行应用程序时才发现错误。

(当然我怀疑是否有任何现有的IDE可以为Perl找到这些东西,但至少perl -cw应该可以,不是吗?)

4 个答案:

答案 0 :(得分:3)

两个可能的答案。选择你喜欢的任何一个:

  1. 在Perl中,这由模块的POD指示。无法以编程方式对其进行标记,因此您需要依赖文档。

  2. 任何方法都可以die,或者至少是任何非常重要的方法。它会调用其他东西,可能会调用其他东西等,所以保证不会抛出异常的唯一方法是追踪所有级别的(潜在)调用,以验证那里可能没有任何可能{ {1}}。更加务实,只是假设异常总是可能的,并且相应的代码。

  3. 编辑添加:作为一般规则,Perl5和静态代码分析并没有真正相处得那么好。我的理解是,这是Perl6语言重新设计背后的动机之一,所以你可能会有更好的运气。

答案 1 :(得分:2)

看不到这样的东西,但也许子程序属性可能会让你的一部分?

以下是使用Attribute::Handlers

的小型概念验证

<强> ThrowsExceptionHandler.pm

package ThrowsExceptionHandler;
use Modern::Perl;
use Attribute::Handlers;

our @subs;

sub ThrowsException :ATTR(CODE) {
    push @subs, {
        package  => $_[0],
        symbol   => $_[1],
        subname  => *{$_[1]}{NAME},
        referent => $_[2],
        attr     => $_[3],
        data     => $_[4],
        phase    => $_[5],
        filename => $_[6],
        linenum  => $_[7],
    };
}

sub does_throw {
    my ($class, $subname) = @_;
    (grep { $_->{subname} eq $subname } @subs) ? 1 : 0;
}

1;

<强> example.pl

use Modern::Perl;
use base qw(ThrowsExceptionHandler);

sub baz :ThrowsException {
    die "Throws error";
}

sub foo {
    warn "warning only";
}


say ThrowsExceptionHandler->does_throw( 'baz' );  # => 1
say ThrowsExceptionHandler->does_throw( 'foo' );  # => 0

或许({3}},PPI和/或Perl::Critic的混合物可以适应使用这样的东西吗?

/ I3az /

答案 2 :(得分:-2)

您检查了CPAN吗? Error::TryCatch是一种选择,Exception::Class是另一种选择等等。

另请参阅Object Oriented Exception Handling in Perl

答案 3 :(得分:-3)

来自文档“Exceptions

  1. $ @没有告诉我们错误发生的位置

  2. 我们可以使用自定义函数来解决这个问题:

    sub throw { 我的$ mess = join('',@ _); $ mess = ~s / \ n?$ / \ n /; 我的$ i = 1; local $“=”','“; 包DB; while(my @parts = caller($ i ++)){ 我的$ q; $ q =“'”如果@DB :: args; $ mess。=“ - &gt; $ parts3”。 “at $ parts 1 line $ parts 2 \ n”; } 死得一团糟 }

  3. 有了这个,你也可以参考“CPAN”和“Object Oriented Exception Handling in Perl