


Perlの環境を構築しておきましょう。Mojoliciousをインストールしておきましょう。$ cpanm Mojolicious
$ mojo generate lite_app
[chmod] myapp.pl 744
myapp.plというファイル名プログラムが作成されているので、そのプログラムを実行します。$ morbo myapp.pl
Server available at http://127.0.0.1:3000.
http://localhost:3000にアクセスしてみてください。Welcome to the Mojolicious real-time web framework!
#!/usr/bin/env perl
use utf8; # <この行を挿入
use Mojolicious::Lite;
use utf8;した状態のPerlは、日本語などのマルチバイト文字でも、文字として正しく扱うことができます。# use utf8;していない状態
$ perl -e 'print length "abcあいう";'
# use utf8;した状態
$ perl -Mutf8 -e 'print length "abcあいう";'
# Documentation browser under "/perldoc" # <この行を削除
plugin 'PODRenderer'; # <この行を削除
PODRendererはMojoliciousのプラグインで、perldocを綺麗に見るためのプラグインです。http://localhost:3000/perldocにアクセスして確認してみてください。Welcome to the Mojolicious real-time web framework! # <削除
%= form_for '/' => begin
%= text_field 'body'
%= submit_button '投稿する'
% end
form_for、text_field、submit_buttonなどは、Mojoliciousのhelperという機能で定義されたPerlの関数(サブルーチン)です。helperについては、次回詳しく説明する予定です。
参考になるページ
http://localhost:3000にアクセス)してみてください。
%= submit_button '投稿する'
% end
<p><%= $body %></p> <この行を挿入
<%= $body %>は、テンプレートの中でPerlの変数などを表示するときに使用します。$bodyという変数の値を表示する、という意味になります。index.html.ep)の最後には.epという拡張子がついています。Embedded Perlの頭文字をとったものです。Mojoliciousが標準で使えるテンプレートのシステムを示しています。MojoliciousのテンプレートでPerlのコードを実行させる書き方としては、タグと行の二種類があります。# タグ
<% Perlのコード %>
<%= Perlのコード %>
<%== Perlのコード %>
# 行
% Perlのコード
%= Perlのコード
%== Perlのコード
get '/' => sub {
my $self = shift;
my $body = $self->param('body'); # < この行を追加
$self->param('body')は、フォームから投稿したbodyという名前がついている値を取得します。 my $body = $self->param('body');
$self->stash(body => $body); # < この行を追加
$self->stash()に、値を渡すと、テンプレートでも使えるようになります。bodyに、変数$bodyを渡したので、テンプレートでは$bodyとして使えるようになります。http://localhost:3000にアクセス)してみてください。投稿するボタンをクリックしてみてください。
http://www.yahoo.co.jp/を開いて、ページの情報をコピー&貼り付けして投稿してみましょう。HTTPでいうところのGETでのリクエストです。GETでのリクエストは文字数の制限(おおよそ2KB程度)がありますので、掲示板など、多くのデータを送信する必要がある場合は適しません。POSTによるリクエストを行います。HTTPについては、ネットワークの知識も必須となるので、Perl入学式では深く取り上げません。GETとPOSTであり、それらをうまく使い分けられれば当分は問題ありません。index.html.epの部分をすべてコピーして貼り付けて、post.html.epというテンプレートを作成します。http://localhost:3000/postにアクセスした時に読み込まれます。# @@ index.html.epを貼り付け
@@ post.html.ep # テンプレート名を変更
% layout 'default';
% title '出力'; # タイトルを変更
%= form_for '/post' => method => 'POST' => begin # 投稿先などを変更
%= text_field 'body'
%= submit_button '投稿する'
% end
<p><%= $body %></p>
form_forに書いたmethod => 'POST'で、getではなくpostで送信するようになります。@@ index.html.epの方は、$bodyを表示しないようにしておきます。form_forも忘れずに変更しておきましょう。titleも変更しておきましょう。@@ index.html.ep
% layout 'default';
% title '入力フォーム'; # タイトルを変更
%= form_for '/post' => method => 'POST' => begin # 投稿先などを変更
%= text_field 'body'
%= submit_button '投稿する'
% end
getの部分のコードをすべてコピーして貼り付けます。bodyの処理をしている部分を削除します。get '/' => sub {
my $self = shift;
my $body = $self->param('body'); # 貼り付けしたあと削除
$self->stash(body => $body); # 貼り付けしたあと削除
$self->render('index');
};
bodyの処理が書いてある方を一部変更します。post '/post' => sub { # この行を変更
my $self = shift;
my $body = $self->param('body');
$self->stash(body => $body);
$self->render('post'); # この行を変更
};
paramは、getでもpostでも同じように動作します。http://localhost:3000にアクセス)してみてください。投稿するボタンをクリックしてみてください。postのテンプレートは、index.html.epをコピー&貼り付けして作成しましたが、フォームの部分を両方共変更する必要がありました。Mojoliciousには、テンプレートを共通化する仕組みがあります。%= form_for '/post' => method => 'POST' => begin
%= text_field 'body'
%= submit_button '投稿する'
% end
form.html.epとして定義します。@@ form.html.ep
%= form_for '/post' => method => 'POST' => begin
%= text_field 'body'
%= submit_button '投稿する'
% end
form.heml.epを使うにはincludeという命令を使います。indexの部分は以下のようになります。@@ index.html.ep
% layout 'default';
% title '入力フォーム';
%= include 'form';
postの部分は以下のようになります。@@ post.html.ep
% layout 'default';
% title '出力';
%= include 'form';
<p><%= $body %></p>
http://localhost:3000にアクセス)してみてください。includeを使うことで、共通の部品として利用できます。postの部分を変更します。my $body = $self->param('body'); # この行の後ろに追加
my $datafile = qq{myapp.dat};
open my $fh, '>>', $datafile or die $!;
print $fh qq{$body\n};
close $fh;
openの行は、$datafileを追加モード(>>)で開いています。die)させます。例外を発生させる、とも言います。$!にはエラーの内容が入っています。$fhで操作します。$fhのような変数を、ファイルハンドル、と言います。printのあとにファイルハンドルを書き、その次に出力する文字列を書きます。qq{}は、"(ダブルクォーテーション)と同じ意味です。出力する文字列の中に"があるような場合に使うとエスケープが不要になるので、コードが読みやすくなります。
参考になるページ
closeをした時点でファイルの取り扱いを終えたことが、コードを読む人にもわかります。将来の自分自身のために、ちゃんと閉じておきましょう。
参考になるページ
http://localhost:3000にアクセス)してみてください。morbo myapp.plしたターミナルを確認し、以下のようなエラーが出ているのを確認してください。Wide character in print at myapp.pl line 15.
use utf8;した状態のPerlは、日本語も含め文字をちゃんと扱うように考えられています。Mojoliciousが最終的に出力する文字列に関しては、Mojolicious自体が適切に処理しています。Encodeというモジュールを使います。use Mojolicious::Lite;
use Encode; # < この行を追加
jcode.plやJcode.pmを知っているかもしれませんが、それらのことは、もう忘れてください。モダンなPerlを理解する上での弊害になります。UTF-8にして、use utf8;を書いておくことが推奨されています。use Encode;すると、幾つかの関数が使えるようになります。(エクスポートされる、とも言います)encode_utf8を使ってエンコードした文字列をファイルに書き込むようにします。print $fh qq{$body\n}; # < この行を以下のように変更
↓
print $fh encode_utf8(qq{$body\n});
http://localhost:3000にアクセス)してみてください。@@ index.html.ep)に、どのように表示するかを考えながら書いて行きましょう。% for my $entry (@{$entries}) {
<p><%= $entry %></p>
% }
get '/' => sub {
my $self = shift; # この行の後ろに追加します。
my $datafile = qq{myapp.dat};
open my $fh, '<', $datafile or die $!;
my @entries = <$fh>;
close $fh;
<$fh>のように<と>でくくります。chompを使います。 @entries = map { decode_utf8($_) } @entries;
$self->stash(entries => \@entries);
get '/' => sub {
my $self = shift;
my $datafile = qq{myapp.dat};
open my $fh, '<', $datafile or die $!;
my @entries = <$fh>;
close $fh;
@entries = map {decode_utf8($_)} @entries;
$self->stash(entries => \@entries);
$self->render('index');
};
http://localhost:3000にアクセス)してみてください。myapp.plは、以下のようになります。#!/usr/bin/env perl
use utf8;
use Mojolicious::Lite;
use Encode;
get '/' => sub {
my $self = shift;
my $datafile = qq{myapp.dat};
open my $fh, '<', $datafile or die $!;
my @entries = <$fh>;
close $fh;
@entries = map {decode_utf8($_)} @entries;
$self->stash(entries => \@entries);
$self->render('index');
};
post '/post' => sub {
my $self = shift;
my $body = $self->param('body');
my $datafile = qq{myapp.dat};
open my $fh, '>>', $datafile or die $!;
print $fh encode_utf8(qq{$body\n});
close $fh;
$self->stash(body => $body);
$self->render('post');
};
app->start;
__DATA__
@@ form.html.ep
%= form_for '/post' => method => 'POST' => begin
%= text_field 'body'
%= submit_button '投稿する'
% end
@@ index.html.ep
% layout 'default';
% title '入力フォーム';
%= include 'form';
% for my $entry (@{$entries}) {
<p><%= $entry %></p>
% }
@@ post.html.ep
% layout 'default';
% title '出力';
%= include 'form';
<p><%= $body %></p>
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>