plackの勉強始めました。

plack/PSGIというのが発表されてずいぶん経つけのだけども。

use strict;
use warnings;

use Plack::Request;
use Plack::Response;

my $app = sub {
  my $env = shift;
  my $req = Plack::Request->new( $env );
  my $res = Plack::Response->new();

  $res->status(200);
  $res->content_type('text/html');
  $res->body('hello world');
};

Plack::Responseのとこはシンプルに配列リファレンスにしてもよかったんだけど、インターフェースのはっきりしているオブジェクトにしておくとわかりやすいし、関数の引数に渡したときにも、渡された側からも使いやすいかなと思ってオブジェクトを使うようにしている。

あと、やっぱりMiddleware使いたい場合はbuilder使えばいいというのも覚えた。

use strict;
use warnings;

use Plack::Request;
use Plack::Response;
use Plack::Builder;
use Plack::Session;
use Plack::Session::Store::DBI;

use DBI;

my @connect_args = (
  'dbi:Pg:dbname=sample',
  'hogehoge',
  'fugafuga',
  {
     AutoCommit => 0,
     RaiseError => 1,
     pg_enable_utf8 => 1,
  }
);

my $app = sub {
  my $env = shift;
  my $req = Plack::Request->new( $env );
  my $res = Plack::Response->new();
  my $sess = Plack::Session->new( $env );
 
  my $body = .....;

  $res->status(200);
  $res->content_type('text/html');
  $res->body( $body );
};

builder {
  enable 'Session',
        store => Plack::Session::Store::DBI->new(
            get_dbh => sub { DBI->connect( @connect_args ) }
        );
  enable 'MethodOverride';
  enable 'CSRFBlock';
  $app;
};

こんなかんじ。
Sessionに使うDBIをScope::Container::DBIに任せてみたりもしたのだけど、Starmanで動作させたとき、Scope::Containerの38行目(DESTROYのとこ)で明示的にdisconnectしなかったという旨のメッセージが表示された。DBIとDBD::Pgを最新にしても同様のメッセージが出た。Postgresqlは8.4.9。AutoInactiveDestroy効いてなかったらもっと深刻なエラーで落ちるから関係ないし。よくわからん。来週再確認しよう。