chat.psgi を Mojolicious::Lite で書き直す

昨日の chat.psgi は、 低レベルの Plack アプリケーションで書いていました。その方が Perl/CGI との違いがわかりやすかろうと考えたのですが、 この手のウェブ・アプリケーションに Mojolicious::Lite を使うのがモダン Perl の世界ってやつです。 プロトタイピングに向いているため、 Lamawiki も当初は Mojolicious::Lite で記述しており、 つくりこみの段階が終わった時点から、徐々に依存パッケージを減らしていきました。

Mojolicious::Lite の方が低レベルの Plack アプリケーションよりも手軽な点の一つに、テンプレートも form パラメータもすべて UTF-8エンコーディングになっていることです。 手動で decode/encode する必要がありません。その上、Mojo が融通を効かせてくれるので、コーディングも楽になります。

ということで、昨日の chat.psgiMojolicious::Lite を使った chat.pl へ書き直します。なお、ほとんど同じなので、書き直しが必要な部分だけを差分で抜き出しています。

まずシーバンを plackup から perl へ変更します。

-#!/usr/bin/env plackup
+#!/usr/bin/env perl
 use strict;
 use warnings;

パッケージ Chat::Log で、Plack::Util::Accessor を使って属性を定義していた部分を、 Mojo::Base を使って書き直します。 new メソッドがいらなくなったので削ります。

 package Chat::Log;
 use Encode;
 use File::Spec;
 use Fcntl qw(:flock);
 use Time::Piece;
-use Plack::Util::Accessor qw(dir lines maxlines);
+use Mojo::Base -base;
 
 our $VERSION = '0.01';
 
-sub new { return bless {%{$_[1] || +{}}}, ref $_[0] || $_[0] }
+has [qw(dir lines maxlines)];

MojoUTF-8decode をしてくれた実引数を扱うため、 update メソッドの先頭部分にある decode を削ります。

 sub update {
     my($self, $lines, $name, $message, $reload) = @_;
     for ($lines, $name, $message) {
-        $_ = defined $_ ? decode('UTF-8', $_) : q();
+        $_ = defined $_ ? $_ : q();
         s/\A[ ]+\z//msx;
     }

コントローラは別物になるので、差分ではなく、書き直したものを貼ります。

package Chat::Controller;
use File::Spec;
use Mojolicious::Lite;

my $log = Chat::Log->new(
    'dir' => File::Spec->catdir(qw[. chatlog]),
    'lines' => 10,
    'maxlines' => 1000,
);

get '/' => sub{
    my($self) = @_;
    $self->stash($log->reload);
    $self->render('chat');
};

post '/' => sub{
    my($self) = @_;
    $self->stash($log->update($self->param([qw(lines name message Reload)])));
    $self->render('chat');
};

app->start;

テンプレートも修正します。Mojo は HTML のエスケープを指定しなくてもデフォルトでおこなうので、そのまま、マークアップを書き直すだけで済みます。

 __DATA__
 
-@@ chat.html
+@@ chat.html.ep

-<tr><td colspan="6">Show last <input name="lines" value="{{lines}}" /> lines</td></tr>
-<tr><td colspan="6"><pre>{{messages}}</pre></td></tr>
-<tr>
-<td>Name</td><td><input type="text" name="name" value="{{name}}" /></td>
+<tr><td colspan="6">Show last <input name="lines" value="<%= $lines %>" /> lines</td></tr>
+<tr><td colspan="6"><pre><%= $messages %></pre></td></tr>
+<tr>
+<td>Name</td><td><input type="text" name="name" value="<%= $name %>" /></td>

POD は全部書き直した方が良いでしょうが、ここでは SYNOPSIS の差分だけを抜き出します。

 =head1 SYNOPSIS
 
-    $ plackup chat.psgi
+    $ perl chat.pl daemon