新しいblogに移行しました

新ブログ "All Yout Bugs Are Belong To Ass" に移行しました!

2011-04-13

[Perl]Plack::Middleware::*を作ってみる

いい加減Plackが当たり前のこの頃ですが、いまだにPlack::Middleware::*を作ったことが無かったので、練習してみました。
なお、あまり気にせずに書いていたら、内容がほとんどPlack::Middlewareのドキュメントと似たものになってしまいました。

基本型

以下が、だいたい定型となるコードです。
package Plack::Middleware::OreOre;
use strict;
use warnings;
use parent qw/ Plack::Middleware /;

### enableでオプションを受け取る時に使用
# use Plack::Util::Accessor qw/ oreore watewate soregashisoregashi /;

our $VERSION = '0.01';

sub call {
    my ( $self, $env ) = @_;

    ### ここに処理をかく ###

    $self->app->( $env );
}

1;
__END__
Plack::Middleware::*を作るには、Plack::Middlewareを継承する必要があります。
で、callというメソッドですが、ここに実際の処理を書いてあげて、最後に$self->app->( $env )としてappを実行するようにします。もしHTTPレスポンスを返したい場合は、途中でPlack::Response形式のarrayrefをreturnしてあげればOKです。
もしenableするときにオプション値を取りたい(enable "OreOre", foo => 'bar'; とか)場合は、Plack::Util::Accessorを使う必要があります。
多分、これだけあれば大抵の機能をPlackに組み込むことができそうです。

ごく単純な例

ある特定パスにアクセスされた時に、他のページにリダイレクトする、というだけの単純なPlack::Middleware::Hogehogeをつくってみました。
package Plack::Middleware::Hogehoge;
use strict;
use warnings;
use parent qw/ Plack::Middleware /;
use Plack::Util::Accessor qw/ jump_url listen_path /;
our $VERSION = '0.01';

sub call {
    my ( $self, $env ) = @_;
    return [ 301, [ 'Location', $self->jump_url ], [''] ] if $env->{ PATH_INFO } eq $self->listen_path;
    $self->app->( $env );
}

1;
__END__
この場合、実際に使うときは以下の様なpsgiになります。
use Plack::Builder;

my $app = sub { [ 200, [ 'Content-Type', 'text/html' ], ['<h1>hoge!</h1>'] ] };

builder {
    enable "Hogehoge", listen_path => '/yahoo', jump_url => 'http://www.yahoo.co.jp/';
    $app;
};
これをplackupすると、/yahooにアクセスしたときだけYahoo!Japanにリダイレクトされ、それ以外は"hoge!"とかかれたページが表示されます。

ようやく少しはPlackの使い方に慣れてきました!

0 件のコメント: