なぜPerlで例外処理のfinallyが特に必要と感じないかを考えてみた
Perlでは例外を発生させるにはdieを使います。これはJava言語でいうthrowにあたります。例外をキャッチするにはevalを使用します。これはJava言語でいうcatchにあたります。例外が発生したかどうかは$@にメッセージが設定されたかで判定できます。
# Perlの例外処理 eval { # 例外を発生させる処理 } if ($@) { }
Perlには知ってのとおりfinally文がありません。でも特に困るというような話を聞きません。なぜでしょうか。finally文で実行される処理は、ほとんどの場合、外部リソースの解放です。ファイルを閉じたり、一時ファイルを削除したり、DBへの接続を解放したりする処理です。このような処理をfinally文で実行したいという要望があります。
なぜJavaではfinally文は必須なのでしょうか。JavaではGCが「世代別GC」という仕組みを利用しているために、オブジェクトの解放のタイミングをプログラマが把握することができないからです。Javaではファイナライザでリソースの解放を行ってはいけません。ですからfinnaly文は必須のものになっています。
PerlのGCは単純な参照カウント方式を利用していますから、オブジェクトが解放されたタイミングでデストラクタを確実に実行することができます。この位置にリソースの解放のロジックを記述することができるため、finally文は必須の機能とはされていないと感じます。
またrubyはGCがマークアンドスイープなので、「デストラクタは利用しないように設計すべき」です。ですのでfinally文(Rubyではeusure文)はぜひとも必要な機能になります。
Perlにfinally文がないからといって、大きな不便があるかというとないというのが実感です。ですからPerlの例外処理は駄目で、finallyを実装している例外処理はすばらしいという考え方は妥当な評価ではないと思われます。