大規模なCatalystアプリケーションでstashが入り乱れていたので作ってみた。
もしかしたらデバッグの役に立つかもしれない・・・
アプリケーションクラス(${アプリケーションルート}/lib/{アプリケーション名}.pm
,$c
)はCatalystクラスを継承しているので、
Catalystクラスのインスタンス変数stashのアクセッサaroundを加工することでstash書き込み時にログを出力したりできそう。
Catalyst.pm
around stash => sub {
my $orig = shift;
my $c = shift;
my $stash = $orig->($c);
if (@_) {
my $new_stash = @_ > 1 ? {@_} : $_[0];
croak('stash takes a hash or hashref') unless ref $new_stash;
foreach my $key ( keys %$new_stash ) {
$stash->{$key} = $new_stash->{$key};
}
}
return $stash;
};
ゲッターもセッターも同じメソッドを使っているのな。てかこれ本体呼ばれてないよね!?( ゚Д゚ )
引数の処理の仕方はなるほどだと思った。
うむ、やっぱりソースコードを読むと勉強になりますな。
そしてちょっと改造したのがこれ、
Catalyst.pm
use Data::Dumper;
around stash => sub {
my $orig = shift;
my $c = shift;
my $stash = $orig->($c);
if (@_) {
my $new_stash = @_ > 1 ? {@_} : $_[0];
croak('stash takes a hash or hashref') unless ref $new_stash;
foreach my $key ( keys %$new_stash ) {
$stash->{$key} = $new_stash->{$key};
$c->log->debug( sprintf( "Stored \"%s\" to \"%s\" in stash.", $new_stash->{ $key }, $key ) );
}
}
return $stash;
};
でもこれだと$c->stash( 'hogehoge', 'hugahuga' )
や$c->stash( { hogehoge => 'hugahuga' } )
には対応できるけど、
$c->stash->{ hogehoge } = 'hugahuga'
には対応できない。
caller関数を使えば何とかなると対応できると思うけどめんどいからやめた。
どうしてもログを出力したい人はハッシュに直書きしないでください。