evalするなら local $@ しよう
$1とか$@とかの特殊変数はグローバルなので、こいつらを使うときはlocal宣言しようと。
package Oya; use Mouse; sub hoge { eval {die "died"}; "hoge" } 1;
use Oya; use strict; use warnings; my $o = Oya->new; if ($@) {warn "err 1"} warn $o->hoge; if ($@) {warn "err 2"} eval {die "deeeeeeeeeeeeee"}; if ($@) {warn "err 3"}
こんなのを実行すると
% perl m.pl hoge at m.pl line 8. err 2 at m.pl line 9. err 3 at m.pl line 11.
と、使う側でevalしなくても$@が真になってしまうので。
で、何とかするには
package Oya; use Mouse; sub hoge { local $@; eval {die "died"}; "hoge" } 1;
と、evalする前に local $@ してやると
% perl m.pl hoge at m.pl line 8. err 3 at m.pl line 11.
と平和になると。
常識的に考えてモジュール側でlocal宣言するべきなんですが、宗教上の事情などによりモジュールを書き換えるのに激しい抵抗が有る場合は仕方ないので
if ($@) {warn "err 1"} warn $o->hoge; local $@; if ($@) {warn "err 2"} eval {die "deeeeeeeeeeeeee"}; if ($@) {warn "err 3"}
と、モジュールを使う側で宣言してやりましょう。
そういやcatalystでも$1とかを使っててちょっとアレな思いをしたことが。
http://d.hatena.ne.jp/foosin/20090113/1231855262
5.7しか使ってないので、5.8で直ってるかは知りません。