【问题标题】:How to create and to throw exceptions in Perl?如何在 Perl 中创建和抛出异常?
【发布时间】:2021-04-05 22:29:38
【问题描述】:

例如,php 有像 InvalidArgumentException 这样的异常,带有自定义消息“找不到当前组”。

我可以在代码中抛出这个异常。

if ($groupId === 0) {
    throw new InvalidArgumentException('Current group not found');
}

我可以继承这个异常并创建另一个子异常。

异常在 Perl 中是如何工作的?

【问题讨论】:

  • 您可以使用try-catch 块使用Nice::Try。 Nice::Try 还处理异常类,因此您可以根据使用的异常类捕获异常。

标签: perl exception


【解决方案1】:

有多种方法可以做到这一点,但它们不是直接内置在 Perl 中的。

最简单的就是dieeval {}抓到。

eval {
  die "in a fire";
};
if ($@) {
  print "something went wrong";
}

如果您想要try,同样有多种选择。最常见的是Try::Tiny

use Try::Tiny;

try {
  die;
} catch {
  print $_;
};

如果您想成为最前沿的人,Paul Evans 进行了一项研究,以在 Perl 代码中添加一个实际的关键字 try。他以Syntax::Keyword::Try 发布了它的原型,并且最近进行了各种讨论,包括 2021 年的 Fosdem。

现在对于实际的例外情况,按照 Perl 的典型做法,有几种方法可以做到这一点。

die 可以将对象作为其参数,而不仅仅是字符串,因此您几乎可以模仿其他语言的行为。

Throwable 可能是我今天的目标。您可以使用Throwable::Factory 轻松创建大量此类。

use Throwable::Factory
  InvalidArgumentException => [qw( $id )];

sub foo {
  my $group_id = shift;
  unless ($group_id) {
    InvalidArgumentException->throw('Current group not found', id => $group_id);
  }
}

稍后要抓住它,您可以这样做:

use Try::Tiny;

try {
  foo(0);
} catch {
  warn $_;
};

【讨论】:

  • 动态创建异常类很好,但如果我想在一个地方创建所有异常类,并让它们在我的代码库中可用怎么办?使用 Exception::Class,我可以将异常定义为类,一旦它们被加载到任何地方,它们就可以在任何地方使用。我不知道如何对 Throwable::Factory 做同样的事情。
  • @Dave 你能问一个新问题吗?今天晚些时候我会回答。实际上,您创建了一个类并使用 Exporter 使您想要的类可用。
【解决方案2】:

我喜欢使用 JT Smith 的 Ouch 模块,尤其是对于 Web 应用程序。这个例子是结合 Ouch 和 TryTiny

use Ouch;
use Try::Tiny;
sub ProcessFiles {    die "Help, help, I'm being repressed";    }

sub DoLotsOfStuff {
    try {
        ProcessFiles();
    } catch {
        ouch 'That module/sub gave me an err', "died: $_";
    };
}
sub Driver {
    try {
        DoLotsOfStuff();
    } catch {
        if (hug($_)) {
            ouch 404, "Driver: $_"; # the caller wants a numeric code
        }
    }
}

try {
    Driver();
} catch {
    if (kiss(404,$_)) {
        ouch 404, "CallAPI: $_";
    }
}

【讨论】:

  • 如果在导入 Ouch 时传递选项 :trytiny_var,则可以避免对 $_ 的所有特定引用(例如在 hugkiss 中)。此外,对于ouch 的第一个参数,我会坚持使用整数错误代码,尽管这是个人喜好问题。
猜你喜欢
  • 2012-04-14
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 2020-10-21
  • 2014-10-28
  • 2020-12-09
  • 2016-12-24
  • 2015-02-09
相关资源
最近更新 更多