たまーにメモを残すために使ってるLIMILICを自宅サーバからAmazon EC2のマイクロインスタンスに移しました。
ボタンのCSSとpaging以外の見た目に変化はありません
移動する際に、Catalyst(Moose以前)とDBIx::Class、Template-Toolkitという今となるとやや分厚い組み合わせでできていたアプリケーションを、自作フレームワーク、DBIx::Sunny::Schema、Xslateという構成に書き直しました。
- 以前のソースコードはCodeRepos http://svn.coderepos.org/share/websites/limilic
- 新しいソースコードはgithub https://github.com/kazeburo/limilic2
書き換えあたり、DBIx::Sunny::Schemaのfilter機能をフル活用してORMとの機能差を埋めています。例えば記事のデータを引いてきたときに、更新時間をDateTimeオブジェクトにしたり、ユーザ情報やコメント数を別のクエリを発行して取得するなどをfilterを使って実装してあります
sub inflate_article {
my ($row, $self) = @_;
$row->{created_on} = $DTFMT->parse_datetime($row->{created_on});
$row->{created_on}->set_time_zone("Asia/Tokyo");
$row->{user} = $self->retrieve_user( id => $row->{user_id} );
$row->{total_comments} = $self->select_one(q{SELECT COUNT(*) FROM comments WHERE article_id = ?}, $row->{id});
$row->{can_modify} = sub {
my $user = shift;
return if ! $user;
...
};
}
__PACKAGE__->select_row(
'retrieve_article',
id => 'Uint',
q{SELECT * FROM articles WHERE id=?},
\&inflate_article
);
__PACKAGE__->select_all(
'recent_articles',
'offset' => { isa => 'Uint', default => 0 },
q{SELECT * FROM articles WHERE acl_view_mode = 1 ORDER BY id DESC LIMIT ?,11},
\&inflate_article
);
クエリの後ろにCodeRefを渡すと取って来たデータに対してそれを実行してくれます。DBから複数行取って来たときはDBIx::Sunny::Scheme側でloop回してくれるのでコードがシンプルにできます。
上のcan_modifyのようにCodeRefを混ぜ込むことで、オブジェクト要らずになるんじゃねと思ったのですが、Xslateでそのまま動かなかったのでちょっと悩んだ。
例えば、
my $mysub = sub { time };
say $tx->render_string('Time is <: $mysub() :>', {mysub => $mysub});
my $myhash = {
mysub => sub { time }
};
say $tx->render_string('Time is <: $myhash.mysub() :>', {myhash => $myhash});
実行するとこうなる
Time is 1308722386
Text::Xslate: Undefined method mysub called for HASH(0x100878450) (<string>:1) at hoge.pl line 17
----------------------------------------------------------------------------
Time is <: $myhash.mysub() :>
----------------------------------------------------------------------------
Time is
myhashが単なるhashなので、method呼び出せないということなんだろう。
$tx->render_string('
<: my $mysub = $myhash.mysub :>
Time is <: $mysub() :>
', {myhash => $myhash});
とりあえず、こんな感じで今回は逃げておいたんだけど、普通に括弧つけるだけで呼び出せたらいいなと思いました!
追記 20110622
$myhash.mysub()を許すと簡単に組み込みメソッドが増やせなり、それが嫌なので敢えて今のようになってます!ちなみに($myhash.mysub)()でも行けます! / LIMILICをEC2に移してCatalyst+DBIx:… http://htn.to/4yBeTQ
とのコメント頂きました。修正します!