3

Perl 中有没有办法声明一个方法可以抛出错误(或死亡)?

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

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

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

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

4

4 回答 4

3

两个可能的答案。选择您更喜欢的:

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

  2. 任何方法都可以die,或者至少是任何非平凡的方法。它会调用别的东西,它可能会调用别的东西,等等,所以保证不会抛出异常的唯一方法是跟踪所有级别的(潜在)调用,以验证那里没有任何可能的东西die。假设异常总是可能的并相应地编码更为务实。

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

于 2010-04-28T10:28:10.713 回答
2

没有见过这样的事情,但也许子程序属性可能会让你有所作为?

这是一个小的概念证明,使用Attribute::Handlers

抛出异常处理程序.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;

例子.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

也许(混合)PPIPerl::Critic和/或Padre可以适应使用这样的东西?

/I3az/

于 2010-04-28T12:06:53.637 回答
-2

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

另请参阅Perl 中的面向对象异常处理

于 2010-04-28T07:24:12.257 回答
-3

来自文档“例外

  1. $@ 没有告诉我们错误发生在哪里

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

    sub throw { 我的 $mess = join('', @_); $混乱 =~ s/\n?$/\n/; 我的 $i = 1; local $" = "', '"; package DB; while (my @parts = caller($i++)) { my $q; $q = "'" if @DB::args; $mess .= " -> $parts3" . " 在 $parts 1行 $parts 2 \n"; } die $mess; }

有了它,您还可以参考“ CPAN ”和“ Perl 中的面向对象异常处理

于 2010-04-28T07:21:47.700 回答