web-dev-qa-db-ja.com

Perlで例外を処理する最良の方法は何ですか?

Exception.pmとError.pmは、Perlコミュニティで広く使用されていないようです。これは、例外処理のためのevalのフットプリントが大きいためですか?

また、Perlプログラムには、一般的な例外処理に関して、より寛大なポリシーがあるようです。これには説得力のある理由はありますか?

いずれにしても、Perlでの例外処理の最良の方法は何でしょうか?

28
ennuikiller

Perlコミュニティのコンセンサスは Try :: Tiny が例外処理を行うための好ましい方法であるようです。あなたが言及する「寛大な方針」は、おそらく以下の組み合わせによるものです。

  • Perlは完全にオブジェクト指向の言語ではありません。 (例えば、Javaとは対照的に、例外の扱いを避けられない場合)
  • 多くのPerl開発者の背景。 (Cのような言語1 シェルには例外メカニズムがありません。)
  • 人々がPerlを使用する傾向がある種類のタスク。 (テキスト処理とレポート生成用の小さなスクリプトで、例外処理は必要ありません。)
  • Perlには(良い)組み込みの例外メカニズムがありません。

最後の項目は、次のような多くのコードが表示されることを意味しています。

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

これは、try/catch構文を使用しない場合でも例外処理です。しかし、それは壊れやすく、ほとんどの人が考えていない多くの微妙なEdgeケースで壊れます。 Try :: TinyおよびCPANの他の例外処理モジュールは、正しく理解しやすくするために作成されました。

1. Cにはsetjmp()longjmp()があり、非常に大まかな形式の例外処理に使用できます。

49
Michael Carman

$ @はそのままでは絶対にテストしないでください。これはグローバル変数であるため、テスト自体でも変更される可能性があります。

一般的なeval-template:

my $result;

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

実際には、これは最も軽い方法です。それでも、おかしい$ @の振る舞いのための小さな余地は残されていますが、本当に十分に気になることは何もありません。

1
user10922431