Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

perlのクイズ

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が評価されるのはスクリプトの最後になる。