web-dev-qa-db-ja.com

error.pmが提供するPerlでtry catchを適切に使用するにはどうすればよいですか?

Javaのようなtry and catch機能を提供するモジュール Error があることがわかりました。しかし、返される例外を印刷する方法については混乱しています。

次の方法を理解したい

try {
    // do something that will fail!

} catch (Error e) {
    // Print out the exception that occurred
    System.out.println(e.getMessage());
}

スタックトレースでエラーの出力を取得するにはどうすればよいですか?

32
pitchblack408

おそらく Try :: Tiny を使用する方がよいでしょう。これにより、多くの 古いPerlsの落とし穴 を避けることができます。

use Try::Tiny;

try {
        die "foo";
} catch {
        warn "caught error: $_";
};
53
Sinan Ünür

最後に確認しましたが、 エラー は廃止されました。ただし、このモジュールなしで行う方法は次のとおりです。

eval {
    die "Oops!";
    1;
} or do {
    my $e = $@;
    print("Something went wrong: $e\n");
};

基本的に、tryの代わりに eval を使用し、throwの代わりに die を使用して、 $@ 。 evalブロックの最後の真の値は、5.14より古いPerlバージョンで再び使用される前に$@が意図せずに変更されるのを防ぐイディオムの一部です。 P :: C :: P:を参照してください。 :ErrorHandling :: RequireCheckingReturnValueOfEval 詳細については。たとえば、このコードにはこの欠陥があります。

# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
eval {
    die "Oops!";
};
if (my $e = $@) {
    print("Something went wrong: $e\n");
}
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14

しかし、多くのPerl操作は失敗しても例外を発生させないことに注意してください。エラーコードを返すだけです。この動作は、組み込みおよび標準モジュールの autodie で変更できます。 autodieを使用している場合、try/catchを実行する標準的な方法は次のとおりです(autodie perldocから直接)。

use feature qw(switch);

eval {
   use autodie;

   open(my $fh, '<', $some_file);

   my @records = <$fh>;

   # Do things with @records...

   close($fh);

};

given ($@) {
   when (undef)   { say "No error";                    }
   when ('open')  { say "Error from open";             }
   when (':io')   { say "Non-open, IO error.";         }
   when (':all')  { say "All other autodie errors."    }
   default        { say "Not an autodie error at all." }
}

スタックトレースを取得するには、 Carp をご覧ください。

45
Mark Reed

Try :: Tinyよりも少し強力なものが必要な場合は、CPANの TryCatch モジュールを確認してください。