こんなマジック知らなかった。
2012-12-08
はじめまして。こんにちは。kfly8です。
なべこたつみかんみかんみかん!黄色になった手でコードを書きます。
年が明けたら熱海に温泉はっかそん行きたいです。
コードを読んでいると
この処理やらなくていいんじゃないか?
ってこと、よくあると思います。
あるMiddlewareが変な動きをしてました
# app.psgi use strict; use warnings; use utf8; use Plack::Builder; builder { # XXX 今回問題になってしまったSession周りを # よしなにやってくれてるMiddleware enable Hoge::Session => ( session_store => Plack::Session::Store->new( ... ), ); $app; } 1; # Hoge::Session.pm package Hoge::Session use strict; use warnings; use utf8; sub call { my ( $self, $env ) = @_; my %options = ( store => $self->session_store,; ); # XXX ほんとによしなにやってるの?動いてないんじゃないか? if ( $VERY_COMPLEX_CONDITION ) { $options{state} = Session::State->new; } $app = Plack::Middleware::Session->wrap($app, %options); my $res = $app->($env); return $res; } 1;
...
$VERY_COMPLEX_CONDITION はあまりに複雑で人が追うには限界が超えていました。
こんな(ニッチな)問題、、、
解決しなければ、ぐっすり寝れません。
Variable::Magic で $env の書き込み、参照を補足
というわけで、今回紹介するモジュールは、Variable::Magicです。
前置き長くてごめんなさい。
(教えてくれたkarupanerura++)
$app を1枚 wrap します。
# app.psgi use strict; use warnings; use utf8; use Plack::Builder; builder { # XXX 問題のだめな子 enable Hoge::Session => ( session_store => Plack::Session::Store->new( ... ), ); # $env のpsgix.session への書き込みと参照を補足する enable sub { my $app = shift; sub { my $env = shift; use Carp qw/cluck/; use Variable::Magic qw/wizard cast/; # どんなマジックを使ってやろうか定める my $wiz = wizard( # ハッシュから参照されたときに呼び出される fetch => sub { cluck 'fetched!!'; }, # ハッシュに書き込まれたときに呼び出される store => sub { cluck 'stored!!'; }, ); # マジックと関連づける cast %{ $env->{'psgix.session'} }, $wiz, '_default'; return $app->($env); }; }; $app; }
これでエラーログを見れば、書き込みと参照があったのかのびのび観測できます
...
これで晴れて、いらんことが分かって、
セッションにストアする処理が無くなりました。
めでたしめでたし。
Plack::Session が、$env->{'psgix.session'} をSession Storeに
入れるシンプルな仕組みであることが効きます。
もっと言えば、Plack::Middleware の仕様のおかげです。
その他の手段は
tie を使っても、同じことは実現できます。
今回、package を作るのが面倒だったので、Variable::Magic を使ってみました。
蛇足
ちょうどjsのadeventカレンダーでも同じような記事があったので共有します。
こっちはアプリケーションで使おうって話です。
まとめ
$env変数への書き込み、参照を補足して、プリントデバッグしてみましたという話でした。
明日は、Yak!さんです。お楽しみにー。