そんな中、Router::Simpleを弄っていて、「毎度newするの面倒だなあ。connectって毎度書くのも億劫だしぃ。。。」とか思っちゃって、じゃあAttributeにパス書けるようにしたらどうだろうということで、Router::Simple::Attributeなるものをつくってみました。
使い方
use MyApp; use Router::Simple::Attribute; sub root : Path(/) { return 'root'; } sub home : Path(/home/:myname) { return 'ok, '. shift->{ myname }. '!'; } router->do( '/' ); # >>> 'root' router->do( '/home/ytnobody' ); # >>> 'ok, ytnobody!'
podをコピってきただけなんですけど、とりあえず簡単に説明。
Pathアトリビュートのついたサブルーチンを作ると、Router::Simple->connect相当のことをやってくれます。アトリビュートオプションには、Router::Simple流のパス文字列を渡してやるといいです。
それから、router()という関数が使えるようになります。こいつはRouter::Simpleのインスタンスを返しますが、これにはdoというメソッドが追加されています。
doメソッドは、Router::Simple::match()の返り値(=HashRef)の要素{code}をコードリファレンスとして実行するものです。
素のRouter::Simpleの場合、
$router->connect( '/path/:user', { code => sub { ... } } ) ... if ( my $p = $router->match( $env ) ) { $p->{code}->( ... ); } else { ... }こんなふうに { code => sub { ... } } のところとか if文のくだりが若干冗長に感じますが、R::S::Attributeなら、
sub user :Path(/path/:user) { ... } ... return router->do( $env ) || [ 404, [], ['not-found'] ];みたいな書き方が可能です。
但し書き
当然ですが、Router::Simpleに処理を追加しているモジュールなので、Router::Simpleより遅いです。あと、例によってテストが少なく、自分でもまだ実戦投入できていないものなので、信頼性については「?」という具合です。とはいえ、R::S::Attribute自体のコード量は非常に少なく、Router::Simpleが安定しているので、何か問題があったとしても、トレースはしやすいとおもいます。
2011-3-4 追記
どうやら、Plack::Sandbox::*とAttribute::Handlersの相性が悪いらしく、plackupからうまく利用できませんでした。
この辺を調査した時の記録は、こちらの記事に書きました。
一つ言えるのは、Attribute::Handlers や Perl5のアトリビュートを使うのは筋がよろしくないということです。
0 件のコメント:
コメントを投稿