use MyObject;
my %data;
eval{
print "Block START\n";
my $mo = MyObject->new();
$data{MYOBJ} = $mo; #←ここを削除
die "Error occurred\n";
print "Block END\n";
};
print "error: $@" if($@);
【実行結果】
Block START
error: Error occurred
上記のスクリプトと実行結果がある。このスクリプトで、「ここを削除」の部分を消すと、エラーがキャッチできなくなる。つまり、「error: Error occurred」が表示されなくなる。これは一体なぜ?
ハッシュにデータを突っ込むか突っ込まないかだけで現象が変わるって言うのは、一見奇妙だ。原因はMyObjectにある。
ちなみにこれは、実際に現場であったバグ(--;。
2009-04-14追記 答え
なんか答え書いてなかったので、4年越しで書いてみる。
package MyObject; use Moose; sub DESTROY { eval {}; } no Moose;
evalが終わるとMyObjectが破棄されるが、その際にDESTROYが呼ばれ、DESTORYの中で$@が書き換えられている。
evalの外のハッシュにデータを突っ込んでいれば、オブジェクトが保持されるのでDESTROYが評価されるのはスクリプトの最後になる。