What is the best way to handle exceptions in Perl?

前端 未结 3 1373
忘掉有多难
忘掉有多难 2020-12-09 02:12

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

相关标签:
3条回答
  • 2020-12-09 03:02

    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.

    0 讨论(0)
  • 2020-12-09 03:06

    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.

    0 讨论(0)
  • 2020-12-09 03:12

    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

    0 讨论(0)
提交回复
热议问题