Perl 中处理异常的最佳方法是什么?

发布于 2024-09-28 22:25:30 字数 175 浏览 3 评论 0原文

我注意到 Exception.pm 和 Error.pm 似乎并没有在 Perl 社区中广泛使用。这是因为异常处理的 eval 占用空间很大吗?

另外,Perl 程序对于异常处理一般来说似乎有更宽松的政策。这有令人信服的理由吗?

无论如何,Perl 中异常处理的最佳方法是什么?

I've noticed that Exception.pm and Error.pm don't seem to be extensively used in the Perl community. Is that due to the large footprint of eval for exception handling?

Also Perl programs appear to have a much more lenient policy regarding exception handling in general. Is there a compelling reason for this?

In any event what would be the best method for exception handling in Perl?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻泪 2024-10-05 22:25:30

Perl 社区的共识似乎是 Try::Tiny 是首选方式异常处理。您提到的“宽松政策”可能是由于以下原因的组合:

  • Perl 不是一种完全面向对象的语言。 (例如,与 Java 相比,其中
    你无法避免处理异常。)
  • 许多 Perl 开发人员的背景。 (像 C1 和 shell 这样的语言没有
    异常机制。)
  • 人们倾向于使用 Perl 来完成此类任务。 (用于文本修改的小脚本和
    不需要异常处理的报告生成。)
  • Perl 没有(好的)内置异常机制。

请注意,最后一项意味着您将看到很多这样的代码:

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}

这是异常处理,即使它不使用 try/catch 语法。但它很脆弱,并且会在许多大多数人没有想到的微妙边缘情况下崩溃。 Try::Tiny 和 CPAN 上的其他异常处理模块的编写是为了更容易正确处理。

<子>1。 C 确实有 setjmp()longjmp(),它们可用于非常粗略的异常处理形式。

The consensus of the Perl community seems to be that Try::Tiny is the preferred way of doing exception handling. The "lenient policy" you refer to is probably due to a combination of:

  • Perl not being a fully object-oriented language. (e.g. in contrast to Java where
    you can't avoid dealing with exceptions.)
  • The background of many Perl developers. (Languages like C1 and shell don't have
    exception mechanisms.)
  • The kind of tasks people tend to use Perl for. (Small scripts for text munging and
    report generation where exception handling isn't needed.)
  • Perl not having a (good) built-in exception mechanism.

Note that the last item means that you'll see a lot of code like this:

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}

That's exception handling even though it doesn't use try/catch syntax. It's fragile, though, and will break in a number of subtle edge cases that most people don't think about. Try::Tiny and the other exception handling modules on CPAN were written to make it easier to get right.

1. C does have setjmp() and longjmp(), which can be used for a very crude form of exception handling.

三寸金莲 2024-10-05 22:25:30

切勿按原样测试 $@,因为它是一个全局变量,因此即使测试本身也可以更改它。

通用评估模板:

my $result;

eval {
    $result= something();
    # ...
    1;  # ok
} or do {
    my $eval_error= $@ || "error";
    # ...
    die $eval_error;
};  # needs a semicolon

在实践中这是最简单的方法。它仍然为有趣的 $@ 行为留下了很小的空间,但没有什么真正让我担心的。

Never test $@ as is, because it is a global variable, so even the test itself can change it.

General eval-template:

my $result;

eval {
    $result= something();
    # ...
    1;  # ok
} or do {
    my $eval_error= $@ || "error";
    # ...
    die $eval_error;
};  # needs a semicolon

In practice that is the lightest way. It still leaves a tiny room for funny $@ behaviour, but nothing that really concerned me enough.

各空 2024-10-05 22:25:30

正如已经提到的,您可以使用传统方式 eval,但如果您愿意要使用更复杂的异常捕获(包括异常对象),那么我建议使用 try-catch-finally 块。
有相当多的 Perl 模块提供了它,例如 Nice::TrySyntax::Keyword::Try,但是 Syntax::Keyword::Try 不提供异常变量赋值或异常类捕获,如

  try
  {
    # something
  }
  catch( Exception $e )
  {
    # catch this in $e
  }

完全披露:我是开发人员Nice::Try

As it has been mentioned you can use the traditional way with eval, but if you want to use more elaborate exception trapping, including with exception objects, then I recommend using the try-catch-finally blocks.
There are quite a few perl modules that provide it such as Nice::Try and Syntax::Keyword::Try, but Syntax::Keyword::Try does not provide exception variable assignment or exception class catch like

  try
  {
    # something
  }
  catch( Exception $e )
  {
    # catch this in $e
  }

Full disclosure: I am the developer of Nice::Try

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文