天然パーマです。

Catalystで作る占いアプリ!

Perlで何かしらのアプリケーションを作りたい!という要望の中にはWebアプリケーションという選択が多く含まれています。 ただ、Webアプリケーションを始めるのにいいキッカケが最近Web上のドキュメンに無い気がします。 そこで、僕が一番最初に手にして今でも使っている、Web Application Framework = WAF の Catalyst を例に紹介しましょう。 Catalystに限らず WAF はMVCモデルを採用しているものがだいたいなのでその概念は知っておいた方がいいかもしれません。が、習うより慣れろの部分もあるので今回は例として占いアプリを作ってみます。

1. Catalystをインストールする

おそらく今回の行程でこれが一番難しいですw CPANシェル、もしくは cpanminus 等を使って適当な場所にインストールしてください。 依存モジュールが多いので時間がかかります。コーヒーを用意しましょう。

 $ cpanm Catalyst

2. ひな形を作る

見事インストールできたら catalyst.pl コマンドが使えます。 今回はシンプルに「Uranai」という名前でアプリを作ります。

 $ catalyst.pl Uranai

3. テストサーバを起動する

Catalyst にはテスト用のサーバが付属しています。-r オプションは更新ファイルがあったら再起動、 -d オプションはデバグモードにするという意味です。たぶん。

 $ cd Uranai/
$ ./script/uranai_server.pl -r -d

4. 確認する

デフォルトではそのホストの3000番ポートで起動します。ブラウザから確認して、 かっこいいロゴ画面がでるのを確認しましょう。

http://localhost:3000/

5. Viewクラスを作る

さて、オリジナルのHTMLを表示したいものです。Viewと呼ばれる表示系のクラスを作ります。

 $ ./script/uranai_create.pl view TT TT

そして、lib/Uranai/Controller/Root.pm の index メソッドを以下のように書き換えると、 自然とそのパスに応じてテンプレートファイルが呼び出されるようになります。 この場合は index.tt というファイルです。

 sub index :Path :Args(0) {
    my ( $self, $c ) = @_;
}

index.tt が無いので作ります。 今回の占いアプリはフォームに名前を入れてもらうとそれをハッシュ関数というものに渡して、 占いの結果からその名前に対応するものを表示するページへ遷移するという仕様になっています。 なのでフォームを書き書きします。

 <!-- root/index.tt -->

<h1>Uranau</h1>

<form action="[% c.uri_for('/uranau') %]" method="get">
    <input type="text" name="name" />
    <input type="submit" value="占う" />
</form>

ついでに、結果表示のテンプレートも書いちゃいます。 今は何書いてるか分からなくてもそのうちわかります。 ちなみにテンプレートエンジンはTemplate-Toolkitというものを今回は使っているので、 そのドキュメントを見るといろいろな応用の仕方がわかりますね。

 <!-- root/uranau.tt -->

<h1>Result</h1>

<p>[% c.req.param('name') | html %]さん、[% result | html %]</p>

6. モデルを作る

次に実際に占いのロジックが走るモデルを作ります。

 $ ./script/uranai_create.pl model Uranai

以下がひな形で作られたものを改造したその占いクラスなのですが、 use Moose; なんてしてるものですからわかりにくいかもですね。 ようは結果のテキストが入ってるリストを定義して、 uranauメソッドでは名前を受け取ってハッシュ関数に渡して、返却された値に対応する リストの要素を返すとしてます。

 package Uranai::Model::Uranai;
use Moose;
use namespace::autoclean;
use Encode;
use utf8;
extends 'Catalyst::Model';

has 'lists' => (
    is      => 'ro',
    isa     => 'ArrayRef',
    default => sub {
        [
            qw/あなたは結婚できません。
              あなたは不幸に会います。
              あなたは貧乏になります。
              あなたは事故にあいます。
              あなたは死にます。
              /
        ];
    },
    auto_deref => 1,
);

sub uranau {
    my ($self, $name ) = @_;
    my @lists = $self->lists;
    my $number = $self->get_number( $name, $#lists + 1 );
    return encode_utf8( $lists[$number] );
}

sub get_number {
    my ($self, $str, $max) = @_;
    my $num = 0;
    $num += ord( $_ ) for split //, $str;
    return $num % $max;
}

__PACKAGE__->meta->make_immutable;

1;

ちなみにハッシュ関数とはある値を与えると決まってある違う値が戻るという関数です。 たぶん。

7. Controllerに追加する

最後に実際に占いの結果を見せる、http://localhost:3000/uranau というページを作ります。 先ほどの Root.pm に uranau メソッドを作ります。アトリビュートという特殊なもので Local と指定しています。ここ、なんて書くかによって挙動変わりますので、ドキュメントで確認してくださいね。

 
# lib/Uranai/Controller/Root.pm

sub uranau :Local {
    my ( $self, $c ) = @_;
    my $name = $c->req->param('name');
    unless( $name ) {
        $c->forward('/default');
        return;
    }
    my $result = $c->model('Uranai')->uranau( $name );
    $c->stash->{result} = $result;
}

$c->req->param('name') でクエリパラメータを取得し、もし入ってなければ default というメソッドへ飛ばし、404を出しています。 そして上記のモデル Uranai さんを呼び出すには $c->model('Uranai') として結果をもらってます。 $c->stash->{result} ってのでテンプレートに値が渡るんですね。

はい!できました! スクリーンショットはこれ!

cat

cat

Enjoy Catalyst!!


PerlフレームワークCatalyst完全入門
posted with yusukebe.com::AmazonSearch on 2010.7.2
  • 山田 祥寛
  • 単行本(ソフトカバー) / インプレスジャパン
  • Amazon 売り上げランキング: 180030
Amazon.co.jpで詳細を見る

モダンPerl入門 (CodeZine BOOKS)
posted with yusukebe.com::AmazonSearch on 2010.7.2
  • 牧 大輔
  • 大型本 / 翔泳社
  • Amazon 売り上げランキング: 60987
  • Amazon おすすめ度の平均: 4.0
    • 4 これがいつまで 「モダン」なのか
    • 3 日曜Pgには難しいです。
    • 5 perl経験者は読んで損はしない
    • 5 Perl中級者におすすめしたい
Amazon.co.jpで詳細を見る