Skip to content

Latest commit

 

History

History
1941 lines (1452 loc) · 73.7 KB

slide.md

File metadata and controls

1941 lines (1452 loc) · 73.7 KB

Perl入学式

第5回 サブルーチン / Webアプリ編


諸注意

  • 会場について

    • 飲食・喫煙・トイレetc
  • 写真撮影について

    • 写真撮影NGな方は、お手数ですが申し出てください

    • 写真はPerl普及団体の JPA ( Japan Perl Association )への活動報告に利用します


講師紹介リファレンス

  • 講師・サポーター紹介

皆さんで自己紹介

  • せっかく今日集まったので、テーブルで自己紹介をしましょう。

  • 話題は自由ですが、以下がオススメです。

    • 名前(ハンドルネーム)

    • なぜPerlを勉強してみようと思ったか

    • なぜPerl入学式に参加してみようと思ったか

    • 前回参加してからの学習の進捗


今日の流れ

  • サブルーチン

  • Webアプリ、その前に

  • HTTP の基礎

  • Mojolicious の準備

  • Mojolicious とは

  • Mojolicious::Lite

  • Mojolicious 入門

  • 簡易 BBS の作成


サブルーチン


サブルーチン

サブルーチンとは?

プログラムの中で、意味や内容がまとまっている作業をひとかたまりにしたものを サブルーチン と呼びます。

Perlにおけるサブルーチンは、「関数」とほぼ同義です。


サブルーチン

サブルーチンと組み込み関数

Perlには、これまで使ってきた printjoin など、Perlが提供する関数(組み込み関数)が用意されています。

サブルーチンを使うことで、 printjoin のように、「特定の処理を行うコード」をひとかたまりにして、 簡単に呼ぶことが出来るようになります。


サブルーチン

サブルーチンの定義

それでは、早速サブルーチンを定義していきましょう。

今回は、末尾に自動的に改行(\n)を付与しながら文字列を表示する say というサブルーチンを定義してみます。


サブルーチン

サブルーチンの定義

sub say {               # -┐
    my $str = shift @_; #  │ サブルーチン say を
    print "$str\n";     #  │ 定義しているところ
}                       # -┘
say("hello, world!"); # hello, world!

Perlでサブルーチンを定義する為には、sub サブルーチン名 { ... } と書きます。

それでは、詳しく見て行きましょう。


サブルーチン

サブルーチンの命名規則

sub say { ... }
  • 末尾の } の後に、 ; を書く必要はありません。

  • サブルーチン名として使える文字は以下です。

    • 大文字・小文字の英数字
    • アンダースコア(_)
  • ただし、サブルーチン名の先頭文字には以下の制限があります。

    • 英文字
    • _

これは変数名と同じルールです。


サブルーチン

Perlにおけるサブルーチンの命名規則

sub say_hello_world { ... }

sub say_good_morning { ... }

複数の単語でサブルーチン名を構築する時は、このように単語間を _ で繋げる場合が多いです。

このような _ で単語をつなげる記法をスネークケース(snake_case)といいます。

Perlでは基本的にスネークケースを推奨しています。


サブルーチン

サブルーチン命名規則クイズ

sub hoge!    { ... }

sub _hoge    { ... }

sub 123_hoge    { ... }

sub hoge_123 { ... }

この中で、サブルーチン名として正しいものはどれでしょうか?


サブルーチン

サブルーチン命名規則クイズの正解

sub hoge!    { ... }    # 記号 '!' はサブルーチン名に使えない

sub _hoge    { ... }

sub 123_hoge    { ... } # 先頭は 英字 or '_' のみ
                        # 数字は先頭に使えない
sub hoge_123 { ... }

正解は _hogehoge_123 です。


サブルーチン

サブルーチンの呼び出し

say('Hello Perl');

定義したサブルーチンは、定義したサブルーチン名の後ろに () を付けることで利用できます。

行末に書く場合には、 ; が必要です。

このようにサブルーチンを利用することを「サブルーチンの呼び出し」といいます。

サブルーチンに値(引数)を渡したい場合、 () の中に書きます。

() を使わずに, サブルーチン名の先頭に & を付けて &say で呼びだすこともできますが、古い書き方なので使わないようにしましょう。


サブルーチン

サブルーチンの引数

sub say {
    my $str = shift @_; # ←┐
    print "$str\n";     #  │ サブルーチンの引数 'Hello Perl' は
}                       #  │ @_ という配列に格納される
                        #
say('Hello Perl');      # ─┘

サブルーチンに与えられた引数は、 @_ という配列に格納されます。

2行目では、shift を使って、この @_ の先頭の要素を取得しています。

このサブルーチンを say('hoge'); のように呼んだ場合、 @_ の中身は('hoge') となり、 $str には hoge という文字列が入ります。


サブルーチン

サブルーチンの引数

sub say {
    my $str = shift;  # @_ が省略されている
    print "$str\n";
}

say('Hello Perl');    # Hello Perl

@_ は、省略することができます。

その為、2行目の my $str = shift; は、 my $str = shift @_; と同じ意味になります。


サブルーチン

サブルーチンの位置

say('Hello Perl');  # Hello Perl

sub say {
    my $str = shift;
    print "$str\n";
}

同じファイル内であれば、サブルーチンの位置にかかわらず say('hoge'); として呼び出すことができます。

ファイル末尾にサブルーチンがまとまっている方が見やすい場合は、このスタイルで書きましょう。


サブルーチン

サブルーチン「add」を作る

sub add {                     #
    my ($left, $right) = @_;  # │サブルーチン add の定義部
    return $left + $right;    #
}                             #

my $result = add(2, 5);       # サブルーチン add の呼び出し
print $result . "\n";   # 7

次に、2つの引数を受け取り、その和を返すサブルーチン add を考えてみることにします。

add サブルーチンの定義と呼び出しは、このように書くことができます。


サブルーチン

サブルーチンに複数の引数を渡す

sub add {
    my ($left, $right) = @_;  # @_ の中に 2, 5が入る
    return $left + $right;    #
}                             #
                              #
my $result = add(2, 5);       # ┘ add の引数 2, 5
print $result . "\n";   # 7

サブルーチンに複数の引数が与えられた場合(この場合は 25 )、サブルーチン側ではこのようにして受け取ることができます。

サブルーチンに複数の引数を与える時は、( ) の中で配列のようにカンマ , で区切って渡します。


サブルーチン

サブルーチン側の引数の受け取り方

sub add {
                        # @_ を省略した場合
    my $left  = shift;  # @_ の先頭から1つ取り出して変数に入れている
    my $right = shift;  # @_ の先頭から1つ取り出して変数に入れている
    return $left + $right;
}
my $result = add(2, 5);
sub add {
    my $left  = $_[0];  # $_[0] : @_ の最初の要素
    my $right = $_[1];  # $_[1] : @_ の次の要素
    return $left + $right;
}
my $result = add(2, 5);

先程の引数の受け取り方は、上記のコードと同じ意味になります。


サブルーチン

返り値とreturn

sub add {
    my ($left, $right) = @_;
    return $left + $right;  # $left + $right の結果を返す
}
my $result = add(2, 5);
print $result . "\n";   # 7

サブルーチンは, return を使うことで、任意のデータを呼び出し元へ返すことができます。

サブルーチンや関数の処理結果のことを 返り値かえりち といいます。

この場合、 $left + $right の計算結果が呼び出し元へ返され、 $result に格納されます。


サブルーチン

複数のreturn

sub is_same {
    my ( $left, $right ) = @_;
    if ( $left eq $right ) {
        print "true\n";    # $left と $right が等しければ表示
        return 1;
    }
    else {
        print "false\n";    # $left と $right が異なれば表示
        return 0;
    }
    print "YOU WILL NEVER SEE IT\n"; # 絶対に表示されない!
    return;
}

returnはサブルーチンの中に複数個書くことができます。

returnに到達した場合、それ以降の処理は一切行われず、すぐさま値を返してサブルーチンの実行を終了します。(ガード節といいます)


サブルーチン

複数の返り値

sub add_and_min {
    my ( $left, $right ) = @_;
    return ( $left + $right, $left - $right );
}
my ( $add, $min ) = add_and_min( 5, 4 );

サブルーチンは、このようにリストを返すことで複数個の値を返すこともできます。

引数がどのようにサブルーチンに渡されて処理されるか、追ってみましょう。


サブルーチン

returnがない場合の返り値

sub add {
    my ($left, $right) = @_;
    $left + $right;         # サブルーチンの中で最後に評価された行
}

my $result = add(2, 5);
print $result . "\n";   # 7

サブルーチンの中に return がない場合、サブルーチンの返り値は最後に評価された処理の結果(この場合、 $left + $rightの計算結果)を返します。

値を返すという意図を明確にするため、 return は書くようにしましょう。


練習問題

次のようなサブルーチンを持つコードを simple_calc.pl という名前で作成しよう。

  • 2つの引数の和(足し算)を計算する add
  • 2つの引数の差(引き算)を計算する min
  • 2つの引数の積(掛け算)を計算する mul
  • 2つの引数の商(割り算)を計算する div

これらのサブルーチンが正しく実装できているか(与えた2つの引数に対して, 適切な値を返すか)を確認するコードも一緒に書くこと。

  • 時間の余った人は「0」で割った際のエラーを回避する仕組みを入れてみよう

  • さらに時間の余った人は数字以外が入力された場合に 'INPUT NUMBER PLEASE'と表示する仕組みを入れてみよう


Webアプリ、その前に


Webアプリ、その前に

アプリとは?

ワープロや表計算などといった、コンピュータを「応用」する目的に応じた、コンピュータ・プログラムである。

Webアプリ、その前に

Webアプリとは?

**インターネット(もしくはイントラネット)などのネットワークを介して使用するアプリケーションソフトウェアである。**

多くの場合、これらのアプリケーションは、Webブラウザ上で動作するプログラミング言語(たとえばJavaScript)によるプログラムと

Webサーバ側のプログラム

が協調することによって動作し、ユーザはそれをWebブラウザ上で使用する。

Webアプリ、その前に

Webアプリとは?

この Webサーバ側のプログラム(スクリプト) を今回の講義で作成していきます。


Webアプリ、その前に

これまでのスクリプトの動き

  1. スクリプトを作る
  2. ターミナルで実行し、入力待ち状態になる
  3. ターミナルの標準入力から入力する
  4. 入力された内容を、スクリプトが処理する
  5. ターミナルの標準出力に、結果が表示される

Webアプリ、その前に

これまでのスクリプトの動き(イラスト)

これまでのスクリプトの動き


Webアプリ、その前に

今回作成するWebアプリの動き

  1. スクリプトを作る
  2. ターミナルで実行し
  3. Webブラウザに画面が表示される
  4. Webブラウザの入力フォームに入力する
  5. 入力された内容を、サーバーでスクリプトが処理する
  6. Webブラウザに、結果が表示される

Webアプリ、その前に

今回作成するWebアプリの動き(イラスト)

これまでのスクリプトの動き


Mojoliciousモジョリシャス
の準備


Mojolicious の準備

モジュールのインストール

プログラムにおいて、必要とされる機能を第三者にも扱えるようにまとめたものを、**モジュール(ライブラリ)**といいます。

第4回目でData::Dumper モジュールを使いましたが、それは Perl に最初から入っている組み込みモジュールでした。

これから学習していく Mojolicious は外部から追加しなくてはならないモジュールです。

モジュールのインストール方法は様々な方法がありますが、この講義では local::lib と cpanm を使って入れることにします。


Mojolicious の準備

local::lib

local::libローカル リブは、モジュールを自分のホームディレクトリで管理することができるモジュールです。

local::lib を使うことで、システム全体への影響を抑えることができます。


Mojolicious の準備

cpanm (cpan minus)

Perlのモジュールの多くはMetaCPANメタ シーパンで公開されています。

このサイトや、GitHubからターミナルでモジュールをインストールすることができるモジュールが cpanmシーパンエム です。

cpanm は通常、 perl が入っているディレクトリにモジュールをインストールしますが、 -l オプションで指定することで、任意のディレクトリにインストールすることが可能です。

この講義では、自分のホームディレクトリ配下にモジュールをインストールします。


Mojolicious の準備

Mojolicious のインストール

ターミナルで以下のコマンドを一つずつ打っていきます。 先頭の $ はターミナルで一般権限ユーザの時に表示されるもので、入力は不要です。

$ curl -L cpanmin.us -o cpanm
$ chmod +x cpanm
$ ./cpanm -l ~/extlib local::lib
$ perl -I ~/extlib/lib/perl5 -Mlocal::lib=~/extlib | tee -a ~/.bash_profile
$ exec $SHELL -l
$ ./cpanm Mojolicious

インストールに躓いたり, エラーが出た時はサポーターを呼んだり、Slackでエラーメッセージを貼り付けて聞いてみてください。


Mojolicious の準備

Mojolicious のインストール

先ほど入力したものの詳細はこちらです。

# curlコマンドでcpanminusプログラムをダウンロードし、cpanmという名前で保存する
$ curl -L cpanmin.us -o cpanm

# cpanmに実行権限をつける
$ chmod +x cpanm

# cpanmの -l(エル)オプションで、指定したディレクトリ(extlib)に指定したモジュール(local::lib)を
インストールする
$ ./cpanm -l ~/extlib local::lib

# perlのモジュール検索パスを追加し(~/extlib/lib/perl5)、extlibにパスを通すための設定を表示
# それをteeコマンドを利用して起動時のシェル設定ファイルにも書き込む
$ perl -I ~/extlib/lib/perl5 -Mlocal::lib=~/extlib | tee -a ~/.bash_profile

# シェルを再起動する
$ exec $SHELL -l

# MSYSのみ実行。Windowsでシンボリックリンクを利用することをMSYSに伝える
$ export MSYS=winsymlinks

# -n テストなしでMojoliciousをインストールする。
# 基本的には -n をつけずにインストールを行うが、時間の都合上、Perl入学式ではテストなしでインストールします。
$ ./cpanm -n Mojolicious

Mojolicious の準備

インストールに成否チェック

以下のコマンドをターミナルから実行し、 Mojolicious のバージョン番号が出力されればインストール成功です。

$ perl -MMojolicious -e 'print "$Mojolicious::VERSION\n"'

Mojolicious の準備

モジュールで広がる世界

cpanm を利用することで、 Mojolicious の他にも数多くのモジュールを利用することができます。 気になったモジュールがあれば

$ ./cpanm モジュール名

でインストールして使ってみましょう!

モジュールの検索はmetacpanGitHubを利用します。

「やりたいこと Perl」 でGoogle検索するのもおすすめです。


Mojolicious の準備

モジュールで広がる世界

Perlの有用なモジュールは数多くあるので、全ては紹介できません。ごくごく一部を紹介します。


Mojolicious の準備

モジュールで広がる世界

また、「・・・有用?」というようなモジュールもあります。これらはAcmeアクメモジュールと言われるジョークモジュール群です。

このように、Perlのモジュールの世界は懐が広いのが特徴です。ぜひ下記の参考リンクも見てみてください。


Mojoliciousとは


Mojoliciousとは

WAF

Web アプリケーションフレームワーク(WAFワフ とは、Webサービスを作る際の必須機能や定型の処理を、まとめて提供する仕組みのことです。

framework 「枠組み」「骨組み」「構造」などと和訳できる英単語

Mojoliciousとは

様々なWAF

Mojolicious は Perl の軽量WAF の1つです。

類似の軽量WAF

  • Amon2 (Perl)
  • Sinatra (Ruby)
  • Flask (Python)
  • Express (Node.js)

似ていない(重量級の)WAF

  • Catalyst (Perl)
  • Ruby on Rails (Ruby)

Mojoliciousとは

MVCモデル

WAFでは、機能のまとまりごとに処理を分けて開発を行っていきます。機能の分け方には様々なやり方があり、手法も数多くありますが、ここでは MVCモデル を紹介します。

  • M: Model
    • Viewから受け取ったデータの処理や、Viewに提供するデータの用意を行う
  • V: View
    • 見栄え、データの表示や入力受付、装飾などを行う
  • C: Controller
    • アドレス(URL)ごとに、どのModelやViewを割り当てるかの交通整理役

Mojoliciousとは

MVCモデル(イラスト)

MVCモデル


Mojoliciousとは

MojoliciousでのMVCモデル

MojoliciousはMVCモデルのうち、Modelを除いた「View」と「Controller」の機能を持っています。

では、 Model はどうするのか?


Mojoliciousとは

MVCモデル(イラスト)

MojoliciousではModelを作りこむ必要がある


Mojolicious::Lite


Mojolicious::Lite

最初に

この入門では、難しい表現を避けるために、厳密には正しくない事も書いてあります。

また、講義時間内に収めるために、ごくごく一部のコマンドや機能についてのみ説明しています。

沢山の引数やコマンド、記法については、本家サイトなどのリファレンスをご覧ください。


Mojolicious::Lite

ひな形を作る

Mojoliciousをインストールすると、mojo というコマンドが使えるようになります。ターミナルで以下のコマンドを入力してください。

$ mojo generate lite_app hello_mojo.pl
  • mojo generate lite_app
    • Mojolicious::Lite を利用した小規模アプリ用のひな形を作成するコマンド。
  • hello_mojo.pl
    • 引数。作成するファイル名。

現在のディレクトリに hello_mojo.pl というファイルが作成されていれば成功です。このファイルは雛形であり、このファイルに手を加えてWebアプリケーションを作成していきます。


Mojolicious::Lite

開発用サーバ morbo

Mojoliciousをインストールすると、 morboモーボ というコマンドも使えるようになります。

morbo は開発用のWebアプリケーションサーバです。この morbo コマンドで mojolicious を起動し、ブラウザで表示を確認しつつ、修正やデバッグをしてWebアプリを作成していきます。

インターネット上では主に Apacheアパッチnginxエンジンエックス といったWebサーバと、 Webアプリケーションサーバが連携してWebサービスを提供しています。


Mojolicious::Lite

morboを起動する

ターミナルから、以下のように打ち込んで実行してください。

$ morbo hello_mojo.pl

Web ブラウザで http://127.0.0.1:3000 にアクセスしてみましょう。

画面上に Server available at http://127.0.0.1:3000. と表示されれば起動しています。


Mojolicious::Lite

morboを終了する

ターミナル上で Ctrl(又は Control )キーを押しながら C キーを押します。

ターミナルが入力待ちの状態に戻れば morbo は終了しています。

ブラウザをリロードすると、ページが表示できなきなくなっています。


Mojolicious::Lite

IPアドレスとポート番号

入力したアドレスについては簡単な説明で済ませます。興味のある方はネットワークについて勉強してみましょう!

  • Webにアクセスする際には、対象のサーバのIPアドレスが必要です。

  • 127.0.0.1ローカルループバックアドレスといい、自分自身を指す特殊なIPアドレスです。

  • :3000ポート番号とよばれるものです。通常のhttpサーバは80番ポートを使います。メールの送信(SMTP)には25番、メールの受信には110番、など利用するアプリケーションごとに番号が決められています。


Mojolicious::Lite

コード解説

それでは、先ほど作成した雛形、 hello_mojo.pl の解説を簡単に行なっていきます。

コード全体はこちらからも確認できます。

[GitHub] hello_mojo.pl


Mojolicious::Lite

コード解説(Line 1 - 2)

#!/usr/bin/env perl
use Mojolicious::Lite;

use Mojolicious::Lite; とすることで、Mojolicious の関数が利用できるようになります。

また、自動的に strictwarningsutf8Perl 5.10 feature が有効になります。


Mojolicious::Lite

コード解説(Line 1 - 2)

use strict;         # お約束
use warnings;       # お約束
use utf8;           # スクリプトの中でマルチバイト文字(日本語など)を使う時に書く
use feature ':5.10';# Perl バージョン5.10で用意された関数を利用可能にする

use Mojolicious::Lite; と書くことで、上記の記述を含むことになります。


Mojolicious::Lite

コード解説(Line 4 - 7 )

get '/' => sub {
  my $c = shift;
  $c->render(template => 'index');
};

MVCモデルの Controller の部分です。

ウェブアプリケーションでは、URLごとに処理を変更できると便利です。URLごとに処理を振り分ける機能のことを routerルーターdispatcherディスパッチャーと呼びます。

Mojolicious::Lite では、 情報を取得する GET メソッド用の router として get という関数が用意されています。


Mojolicious::Lite

コード解説(Line 4 - 7 )

get '/' => sub { 省略 };

見慣れない書き方ですが、これは、先に説明した get という関数に、2つの引数を渡しているものです。

1つ目の引数が '/' という文字列、2つ目の引数がコードリファレンス(サブルーチンリファレンス)です。

コードリファレンス(サブルーチンリファレンス)は sub から始まっていますが、先に学習したサブルーチンではありません。サブルーチンのリファレンスです。1点重要な違いとして末尾にセミコロンが必要です。

このように書くことで、GET メソッドで / にアクセスした時、 sub { ... } に書かれている処理が行われます。


Mojolicious::Lite

コード解説(Line 5 - 6 )

my $c = shift;
$c->render(template => 'index');

コードリファレンス内の最初の行は、引数を $c というスカラー変数で受け取っています。この $c はコントローラーの略称と思ってください。

$cの中に入るのは、「どのブラウザからアクセスしてきたか?」「入力項目にどのような値が入っているか?」「どのような操作が可能か?」といった情報の塊、オブジェクトです(詳細は「すぐわかる オブジェクト指向Perl」で)。

コントローラーには render というメソッドがあり、どのような出力をするのかを書くことができます。メソッドは、オブジェクトに紐づいたサブルーチンと思ってください。

ここでは index のテンプレートに出力するように書かかれています。


Mojolicious::Lite

コード解説(Line 9 )

app->start;

コントローラーの処理を書いた後、Mojolicious が用意した app オブジェクトの start メソッドを利用してアプリを起動します。

このコードがないと Mojolicious は起動しません。


Mojolicious::Lite

コード解説(Line 10 )

  __DATA__

__DATA__ この行以降をデータセクションといいます。

Perlはこの行以降は文字通りデータとして扱い、コードとして解釈しなくなります。

Mojolicious::Liteでは、ここにブラウザで表示される部分、MVCフレームワークの View に関するコードを書いていきます。

Mojolicious::Liteでは、Viewをさらに分割しています。

  • ページの内容を記述する「テンプレート部」
  • ページのレイアウトを設定する「レイアウト(レイアウトテンプレート)部」

Mojolicious::Lite

コード解説(Line 12 )

@@ index.html.ep

ここからはページの内容を記述するテンプレート部となります。

Mojolicious::Lite では、 @@ index.html.ep と書くと、次に @@ が出てくるまでの範囲を index.html.ep というファイルとして扱います。

このようにすれば、1つのPerlスクリプトで多くのページを作ることができ、効率的にWebアプリを書くことができます。

ep は、Mojoliciousの標準的なテンプレート機能を使用するための拡張子です。拡張子を ep にすることで、テンプレートであることを示します。


Mojolicious::Lite

コード解説(Line 13 - 15)

% layout 'default';
% title 'Welcome';
<h1>Welcome to the Mojolicious real-time web framework!</h1>
  • layout 関数でレイアウトを指定します。ここでは default を設定しています。(後ほど詳しく説明します)

  • title 関数はタイトルを指定します。ここでは Welcome を設定しています。(後ほど詳しく説明します)

  • それ以外の通常の文字列は、そのままHTMLとして表示されます。


Mojolicious::Lite

コード解説(Line 17 )

@@ layouts/default.html.ep

@@ が書いてあるので「テンプレート部」はこの上の行までとなります。これ以降は「レイアウト(レイアウトテンプレート)部」です。

以下をまとめて書いておくことで、ページごとに記述する手間を省くことができます。

  • <html></html>タグや<head></head>タグ<body></body>などの必須HTMLタグ
  • タイトルロゴや会社案内などのヘッダーやフッターのHTML

また、このレイアウトもテンプレートと同じく、仮想的なファイル layouts/default.html.ep つまり layouts ディレクトリにある default.html.ep というファイルとして扱われます。


Mojolicious::Lite

コード解説(Line 18 - 22 )

<!DOCTYPE html>
<html>
  <head><title> 省略 </title></head>
  <body> 省略 </body>
</html>
  • <!DOCTYPE html> HTMLのバージョン5(HTML5)で書かれていることをブラウザに伝えるHTMLのマークアップ宣言です。
  • <html>...</html> このタグの内部にHTMLを記述します。
  • <head>...</head> このタグの内部にHTMLのヘッダー情報を記述します。
    • <title></title> このタグの内部にページタイトルを記述します
  • <body>...</body> このタグの内部にHTMLの本文を記述します。

Mojolicious::Lite

コード解説(Line 20 - 21 )

HTMLタグの内側に書かれているものについての解説です。

<head><title><%= title %></title></head>
<body><%= content %></body>
  • <%= ... %> (あるいは %= から始まる行)は、Perl のコードを実行するだけでなく、変数の値を表示したい時に書きます。

  • <%= title %> は、14行目で % title 'Welcome'; と指定したので、 Welcome と表示されます。 titleは、Mojoliciousが用意した関数です。

  • content は、レイアウトテンプレート内で使える関数で、テンプレート部(12 - 15行目)の中身がここに代入されます。


Mojolicious::Lite

コード解説(イラスト)

hello_mojoコード解説


Mojolicious 入門


Mojolicious 入門

Controller -> view

morbo が起動していない人はターミナルから以下のコマンドで起動します。

$ morbo hello_mojo.pl

先に作成した hello_mojo.pl のファイルを編集していきます。

[GitHub] hello_mojo.pl


Mojolicious 入門

Controller -> view

まず、Controllerで変数を設定して、それをView(テンプレート)に渡してみましょう。 [GitHub] hello_mojo.pl

get '/' => sub {
  my $c = shift;
  $c->stash( greeting => 'Hello Mojo' );  # この行を追加
  $c->render('index');
};

コントローラー部で $c->stash( greeting => 'Hello Mojo' ); と書くことで、テンプレート内でスカラー変数 $greeting (中身は文字列'Hello Mojo')を利用することが可能になります。

stashメソッドの引数がハッシュ形式であることにも注目です。


Mojolicious 入門

Controller -> view

Controllerで設定した変数を、View(テンプレート)で、表示してみます。 Welcome〜 の行の下に、 <%= $greeting %> と1行追加してください。

[GitHub] hello_mojo.pl

<h1>Welcome to the Mojolicious real-time web framework!</h1>
<%= $greeting %>    # この行を追加

追加したらスクリプトを保存して、ブラウザをリロードしてください。

Hello Mojo と表示されたら成功です。

このように、Controller で設定した変数を、 <%= 変数名 %> という特別なタグをつかってテンプレート内で表示することができます。


Mojolicious 入門

ページの増やし方

つぎに、ページの増やし方です。新たにひな形を作って実践していきます。

$ mojo generate lite_app mojo_prof.pl

$ morbo mojo_prof.pl

作成した mojo_prof.pl を編集していきます。

[GitHub] mojo_prof.pl


Mojolicious 入門

ページの増やし方 Controller

まず、コントローラー部にルーターを追加します。

[GitHub] mojo_prof.pl

get '/' => sub {
  my $c = shift;
  $c->render(template => 'index');
};

# 以下の4行を追加
get '/profile' => sub {             # get関数の最初の引数が
  my $c = shift;                    # /profile となっている
  $c->render(template => 'index');
};

Mojolicious 入門

ページの増やし方 Controller

ここまで入力したら、ブラウザをリロード(再読み込み)してから以下のアドレスにアクセスしてみてください。

同じページが表示されていれば成功です。

また、ルーターを追加していない適当なアドレスを入力して、エラーが出ることを確認してみましょう。


Mojolicious 入門

ページの増やし方 View

では、ページのアドレスごとに表示される内容を変更します。引き続き、mojo_prof.plを編集します。今度はViewのテンプレート部に追加します。

Welcome のメッセージ下にある4行をコピペして追加します。なお、<!-- コメント --> はテンプレート(HTML部分)にコメントを書くときの記法です。[GitHub] mojo_prof.pl

<h1>Welcome to the Mojolicious real-time web framework!</h1>
<!-- <h1>タグの下に以下の4行を追加する -->
@@ profile.html.ep
% layout 'default';
% title 'ぷろふぃーる';
<h1>プロフィール</h1>

@@ layouts/default.html.ep

Mojolicious 入門

ページの増やし方 View

view の用意ができたので、コントローラー部の renderメソッドを変更します。

[GitHub] mojo_prof.pl

  $c->render(template => 'index');
};

# 以下の4行を追加
get '/profile' => sub {
  my $c = shift;
  $c->render(template => 'profile');# ここを index から profile に変更する
};

Mojolicious 入門

ページの増やし方 View

ブラウザをリロード(再読み込み)してから以下のそれぞれのアドレスにアクセスしてみてください。

http://127.0.0.1:3000/profile にアクセスした時に「プロフィール」と表示されていたら成功です。

これでページのアドレスごとに異なる内容を表示することができました。


練習問題

先ほど作成したhttp://127.0.0.1:3000/profileを充実させましょう。以下のページからコードをコピペして利用してもokです。

[GitHub] mojo_prof.pl

@@ profile.html.ep
% layout 'default';
% title 'profile';
<h1>プロフィール</h1>
<p>私の名前は<%= $name %>です</p>
<p>趣味は<%= $hobby %>で, 好きなプログラミング言語は<%= $lang %>です</p>
  1. テンプレート部の profile を、コピペして上記のものに置き換えます。
  2. コントローラー内で stash を利用して name, hobby, lang 変数に値を代入します。
  • 思いつかない人用ハッシュ
    (name => 'larry', hobby => 'study', lang => 'Perl' )

テンプレートの
活用


テンプレートの活用

テンプレートで制御構文

テンプレートは単にHTMLを表示したり、コントローラーで設定した変数を表示するだけではありません。

if文やfor文のような、Perlの制御構文をテンプレート内で記述することができます。

さっそく練習用の雛形を作って実行してみましょう。

[GitHub] mojo_fizzbuzz.pl

$ mojo generate lite_app mojo_fizzbuzz.pl

$ morbo mojo_fizzbuzz.pl

名前から分かる通り、 fizzbuzz をやってきます。


テンプレートの活用

テンプレートでfor文

今回はテンプレートの活用なので、テンプレート部の「Welcome 〜 」の下の行から書いていきます。

[GitHub] mojo_fizzbuzz.pl

<h1>Welcome to the Mojolicious real-time web framework!</h1>
<!-- 以下4行を追加 -->
<% for my $num (1 .. 100){ %>
    <%= $num %>
<% } %>

書き終えたら、ブラウザをリロードしてください。1 から 100 までの数字が表示されていれば成功です。


テンプレートの活用

テンプレートでfor文

では解説します。

<% for my $num (1 .. 100){ %>
  <%= $num %>
<% } %>

テンプレートで利用する特殊なタグを外すとこのようになります。

for my $num (1 .. 100){
  $num
}

Perlで書くfor文とほぼ同じです。


テンプレートの活用

テンプレートでfor文

<% for my $num (1 .. 100){ %>

<% } %>

テンプレートでのfor文ですが、これはそれぞれの行を <% %> というテンプレート用の特殊なタグで囲っています。

<% for my $num (1 .. 100){ %>
  <%= $num %>
<% } %>

そして、forで処理された変数 $num を囲む特殊タグが、forの特殊タグと異なるところに注目してください。


テンプレートの活用

テンプレートでfor文

変数を表示するタグには = があり、Perlの構文を書くタグには = がありません。

  • 変数を表示する : <%= 変数 %>

  • Perlの文を書く: <% Perlの文 %>

このように、その行で何をしているかによって特殊タグを変える必要があります。

なお、変数を表示する際の print は不要です。


テンプレートの活用

テンプレートでif文

引き続き、fizzbuzz.plを編集していきます。

[GitHub] mojo_fizzbuzz.pl

<% for my $num (1 .. 100){ %>
  <% if ($num % 3 == 0 ){ %>
    fizz
  <% } else { %>
    <%= $num %>
  <% } %>
<% } %>

for文の中にif文を書いています。一気に難しくなったようにみえますが、分解して解説していきます。


テンプレートの活用

テンプレートでif文

for文の中のif文の部分だけを取り出してみます。

<% if ($num % 3 == 0 ){ %>
  fizz
<% } else { %>
  <%= $num %>
<% } %>

さらに、テンプレートで利用する特殊なタグを外してみます。

if ($num % 3 == 0 ){
  fizz
} else {
  $num
}

馴染みのある形になったと思います。


テンプレートの活用

テンプレートでif文

<% if ($num % 3 == 0 ){ %>
  fizz
<% } else { %>
  <%= $num %>
<% } %>

ここでもfor文とほぼ同じで、

  • 条件分岐のif文の行は <% %> で囲われている

  • 単に文字を表示するときはその文字 fizz のみ

  • 変数を表示するときは <%= %>

というルールでタグに囲まれています。


練習問題

fizzbuzz を完成させましょう。 [GitHub] mojo_fizzbuzz.pl

  • fizzbuzzのルール

    • 1 から 100 までの数をカウントしていく
    • 3 で割り切れる場合、数字ではなく fizz と表示
    • 5 で割り切れる場合、数字ではなく buzz と表示
    • 3 でも 5 でも割り切れる場合、数字ではなく fizzbuzz と表示
    • いずれも満たさない場合は、その数を表示
  • 時間が余った人向け課題

    • <br> で改行したり、 <font color ='blue'><font color ='red'> などで結果に応じた色をつけてみる
    • テンプレート部ではなく、コントローラー部に fizzbuzz を書いてテンプレート経由で表示する

簡易 BBS の作成


簡易 BBS の作成

簡易BBSの概要

いよいよPerl入学式の講義も最終項目となりました。

これから作るのは、Webアプリの基本形ともいえる BBS、掲示板 です。

電子掲示板(でんしけいじばん、BBS、英語: Bulletin Board System)とは、コンピュータネットワークを使用した環境で、記事を書き込んだり、閲覧したり、コメント(レス)を付けられるようにした仕組みのことである。

簡易 BBS の作成

なぜ簡易BBSが基本形なのか?

簡易BBSを構成する最低限の要素は以下の3つです。

  1. ページが表示できる

  2. ページを経由して情報を送信できる

  3. 送信した内容に応じて、ページ内の情報やサービスが変わる

これは全てのWebアプリで必須の要素であり、簡易BBSを通して実装を学ぶことができます。

Twitter や Instagram、交通情報や天気、音楽アプリやゲームなどでも共通する要素です。


簡易 BBS の作成

CRUD

なお、Webに限らず、アプリの基本要素をまとめたものをCRUDクラッドといい、以下の略称となります。

  • Create: 情報を生成する。

  • Read: 情報を閲覧できる。

  • Update: 情報を更新できる

  • Delete: 情報を削除できる

Perl入学式での簡易BBS作成は、CRUDのうち、 Create と Read を実装します。


簡易 BBS の作成

Perl入学式版BBS

以下を完成形として作っていきます。

  • Webブラウザで表示ができる

  • ページに入力欄がある

  • 入力欄から入力した文字を投稿すると、その文字がページに表示される

  • 複数回投稿すると、投稿した順番でページに表示される


簡易 BBS の作成

雛形をつくる

[GitHub] mojo_bbs.pl

$ mojo generate lite_app mojo_bbs.pl

$ morbo mojo_bbs.pl

作成された mojo_bbs.pl を編集していきます。


簡易 BBS の作成

テンプレート表示の変更

まず、indexテンプレートを変更します。 [GitHub] mojo_bbs.pl

変更前

@@ index.html.ep
% layout 'default';
% title 'Welcome';
<h1>Welcome to the Mojolicious real-time web framework!</h1>

変更後( title と <h1></h1> タグの中身を変更)

@@ index.html.ep
% layout 'default';
% title 'BBS';
<h1>掲示板です</h1>

ブラウザをリロードして、「掲示板です」と表示されるか確認します。


簡易 BBS の作成

入力フォームの作成

入力フォームを設置します。

<h1>掲示板です</h1> の下に、4行追加します。

[GitHub] mojo_bbs.pl

<h1>掲示板です</h1>
<!-- ここから4行追加 -->
<form action="/" method="get">
    <input name="body" type="text">
    <input type="submit" value="投稿する">
</form>

簡易 BBS の作成

入力フォームの作成

追加したら保存します。

ブラウザをリロード (あるいはhttp://127.0.0.1:3000) にアクセス) してみましょう。

入力欄が表示されていれば成功です。


簡易 BBS の作成

クエリ文字列

ここで、入力欄に「hogehoge」といれて「投稿する」ボタンを押してみます。

画面上に変化がないように見えます・・・が、ブラウザのアドレスバーに注目してください。以下のようになっているはずです。

http://127.0.0.1:3000/?body=hogehoge

他の文字を入れた時も、アドレスバーは入力された文字に応じて表示が変わります。

  • body は テンプレートの form タグの name
  • hogehoge は入力内容

この ?body=hogehoge の部分を**クエリ文字列、クエリストリング(query string)**といいます。


簡易 BBS の作成

ここでMVCモデルを思い出す

MVCモデルを思い出しましょう。

いま、入力欄が表示されているのは View です。

この View で入力された情報を View で表示するためには、 一度 Controller に入力内容を渡す必要があります。

そして、Controller から View に情報を渡す必要があります。


簡易 BBS の作成

ここでMVCモデルを思い出す(イラスト)

MojoliciousではModelを作りこむ必要がある


簡易 BBS の作成

View -> Controller

クエリ文字列を使って、View(の中にあるフォーム) から Controller に入力内容を渡します。

(再掲) $cの中に入るのは、「どのブラウザからアクセスしてきたか?」「入力項目にどのような値が入っているか?」「どのような操作が可能か?」といった情報の塊、オブジェクトです(詳細はオブジェクト指向Perlで)。


簡易 BBS の作成

View -> Controller

確認してみましょう。Controllerに、以下のようなデバッグ情報を追加して保存します。

[GitHub] mojo_bbs.pl

get '/' => sub {
  my $c = shift;
  print '-----' ."\n"    ;       # 追加:単なる区切り線
  print $c->param('body') . "\n";# 追加:デバッグプリント
  print '-----' ."\n"    ;       # 追加:単なる区切り線
  $c->render('index');
};

ブラウザをリロードして、適当な内容をフォームに入れて「投稿する」ボタンを押してみましょう。

ターミナルのログの中に、入力した文字が表示されています。


簡易 BBS の作成

View -> Controller

先ほどコントローラー部に追加した4行のうち、デバッグ用の表示部分を除いた肝心の部分はこの1行です。

Mojolicious の get メソッド内にある $c の param メソッドです。

my $entry = $c->param('body'); # 追加

この $cparam メソッドの引数に formname(今回はbody) を指定することで、テンプレート内にある入力フォームから送信された内容を取得することが可能です。


簡易 BBS の作成

View -> Controllerの流れ

このような流れでテンプレート部のフォームの内容をコントローラーが受け取ります。

  1. Viewで表示されたフォームに入力

  2. 「投稿する」ボタンを押す

  3. フォームのname(今回はbody)と入力内容が含まれたクエリ文字列が作成される

  4. クエリ文字列がGETメソッドでサーバー(Mojolicious)に送信される

  5. Mojolicousが送信内容を受け取る


簡易 BBS の作成

Controller -> viewの流れ

受け取った内容をviewに反映させるため、さらに Controller に追加します。

Controller から View に渡す方法は hello_mojo.pl や mojo_prof.pl で実践済みの stash を使います。 [GitHub] mojo_bbs.pl

get '/' => sub {
  my $c = shift;
  my $entry = $c->param('body') ; # クエリストリング body を受け取り $entry に代入
  $c->stash( kakikomi => $entry );# 追加
  $c->render('index');
};

受け取った情報をスカラー変数 $entry に代入しています。そして、$entry をstashメソッドの引数(ハッシュのvalue)として渡しています。


簡易 BBS の作成

Controller -> view

Controller から受け取った情報を表示します。

formタグの下に、以下を追加します。

[GitHub] mojo_bbs.pl

<p><%= $kakikomi %></p>

ここまで出来たら、保存してからブラウザをリロード (あるいはhttp://127.0.0.1:3000にアクセス) してみます。

フォームに文字を入力して、「投稿する」ボタンをクリックし、入力した文字がフォームの下に表示されることを確認します。


簡易 BBS の作成

記事を蓄える

さて、ここまでで投稿した内容をページに表示することができるようになりました。

しかし、再度投稿すると、上書きされてしまいます。

過去に投稿した記事がページに表示されるように変更します。


簡易 BBS の作成

記事を蓄える方法

記事を蓄える場合、主に以下のような方法があります。

  • MySQL や PostgreSQL 、SQLite などのデータベースを使う

  • ファイルを作成し、そのファイルに記事を保存

今回は時間の制約上、データを蓄える方法として配列を使った方法を紹介します。

なお、配列はWebアプリケーションが停止・再起動した時点でデータが消えてしまいます。現実的ではないですが、無駄というわけではありません。

実際には、データベースから抜き出したデータを配列に格納し、Viewに渡す、という用途が多いです。応用が効く方法です。


簡易 BBS の作成

配列を用意する

まず、投稿を保存する配列を用意する必要があります。

[GitHub] mojo_bbs.pl

use Mojolicious::Lite;

my @entries = (); # 追加する

get '/' => sub {

配列は get のコードリファレンスの外で宣言します。なぜでしょう?

コードリファレンスの中で my @entries とすると、 get でアクセスの都度、配列が初期化されてしまい、投稿を貯めることができなくなるためです。


簡易 BBS の作成

配列に投稿を貯める

コントローラーの部分を変更します。

[GitHub] mojo_bbs.pl

get '/' => sub {
    my $c     = shift;
    my $entry = $c->param('body');
    push @entries , $entry;            # 追加
    $c->stash( kakikomi => \@entries );# 変更
    $c->render('index');
};

クエリストリングから取得した記事を配列 @entriespush します。

また、stash メソッドに渡す引数を配列リファレンスに変更します。


簡易 BBS の作成

貯めた投稿を表示する

コントローラーから受け取ったスカラー変数を、テンプレート部で表示しています。

<p><%= $kakikomi %></p>

この時点でブラウザをリロードすると、入力欄の下に ARRAY(0x7fb17f0d1610) などと表示されます。

これは配列リファレンスを print した時と同じです。

コントローラー部からテンプレートへ配列リファレンスが引き渡されていることがわかります。


簡易 BBS の作成

貯めた投稿を表示する

この配列リファレンスをデリファレンスします。配列といえば for 文です。<p>タグで囲まれたところを変更します。 [GitHub] mojo_bbs.pl

変更前

<p><%= $kakikomi %></p>

変更後

<p>
<% for my $kakiko (@{$kakikomi}){ %>
    <%= $kakiko %><br>
<% } %>
</p>

これで、投稿が配列に溜まり続け、また、その投稿が表示されるようになりました。


最終問題

これまで作成してきた簡易 BBS を, 改造してみましょう!

例えば...?

  • 名前/メールアドレスを入力/表示できるようにする

  • メールアドレスが「age」であれば、記事を push ではなく unshift する(一番上に表示される)

  • テンプレートを整理して、見た目を綺麗にする

  • レイアウトにTwitter Bootstrapを使ってみる

などなど。


お疲れ様でした!


お疲れ様でした!

Webアプリの一歩目

非常に簡単ではありますが、BBS (のような) Web サービスを開発してみました。

Perl を使った Web サービス開発の基本的な流れはこのようになっています。

今日ここまで紹介してきた内容は、基礎中の基礎です。

そして、Webサービス全体のうち、「サーバサイド」と呼ばれる部分の一部です。

「 Web サービスを作ろう!」となると、Perl以外にも挑戦しなければならない「壁」はいくつもあります。


お疲れ様でした!

Webアプリ完成までにぶつかる壁(一部)

  • HTMLのコーディング
    • HTML5, WEB標準
  • Webデザイン、Webアクセシビリティ、ユーザーインターフェイス
    • CSS, スタイルシートフレームワーク
  • インタラクティブなサイト作り
    • JavaScript、Javascriptフレームワーク
  • WebサーバとWebアプリケーションサーバの運用管理
    • Apache, nginx, plack, starman
  • データベースの運用管理
    • MySQL, PostgreSQL, SQLite, Oracle
  • ネットワーク
    • ルーティング, CDN, DNS
  • セキュリティ
    • XSS, 各種インジェクション攻撃対策

お疲れ様でした!

大きな一歩

しかし、皆さんは Hello World の表示からはじめて、Webサービスの基礎を学ぶところまでたどり着きました。

同じように、他の分野の知識も一歩一歩着実に学ぶことで身につけることができます。

また、自分ができない分野は、他の誰かが得意な分野かもしれません。

困ったことがあったら、Perl入学式の資料やスタッフを是非頼って下さい!

是非Perl入学式のslackに参加して、 サポーターや参加者の皆さんと交流しましょう。


全5回、お疲れ様でした!


落ち穂拾い 1

HTTP の基礎


HTTP の基礎

用語解説

今回はWebアプリケーションを作っていきますが、その前にWebについて最低限の解説を行います。

皆さんが使っているブラウザと、インターネット上にあるサーバはHTTPというプロトコルを用いて通信を行なっています。

  • HTTP: Hyper Text Transfer Protocol
  • Hyper Text:複数の文書(テキスト)を相互に関連付け、結び付ける仕組み(wikipedia)
  • プロトコル:手順

HTTP の基礎

HTTP のメソッド

HTTPというプロトコルでは、情報の取得を行う**メソッド(方法・手段)**として、主に以下の2つが利用されています。

  • GET : (主に)サーバからデータを取得する

  • POST : (主に)サーバにデータを送信する

このGETとPOSTを利用して、ブラウザとWebアプリ間の情報をやりとりします。


HTTP の基礎

GETの特徴


HTTP の基礎

POSTの特徴

  • 主にサーバーにデータを送信する際に利用

  • サーバーにデータを送る際、URLに情報が含まない

  • POSTの例

    • 日本郵便のページから郵便番号検索した時のURL

    https://www.post.japanpost.jp/cgi-zip/zipcode.php

    • GETの時と違って、入力された情報が移動後のURLの中に含まれない

HTTP の基礎

GET と POST

GET / POST で通信を行なっているのはパソコンで動いているブラウザだけではありません。

Android や iPhone などのスマホのアプリも、インターネットにあるサーバの情報を GET / POST でやりとりしています。

そして、スマホのアプリがつながるインターネット側では、 Perl をはじめ、node.js ( Javascript ) , Ruby, Python, C や Java などのプログラムが動いています。


落ち穂拾い 2

続・簡易 BBS の作成


続・簡易 BBS の作成

POSTメソッド

完成させたBBSのフォームは、GETメソッドを利用してデータを送信していました。

<form action="/" method="get">
(中略)
</form>

GETメソッドを利用する際には、以下の注意が必要です。

  • 送信データは2KB程度(全角で1000文字くらい)が限度

    • 画像データなどは、2KBを軽く超える
  • URLにフォームの内容が残り、セキュリティ上の問題になることも


続・簡易 BBS の作成

GETとPOSTの復習

また、 GET と POST は利用用途で使い分ける方が好ましいです。GETとPOSTの復習です。

  • GET : (主に)サーバからデータを取得する

  • POST : (主に)サーバにデータを送信する


続・簡易 BBS の作成

POSTでのデータやりとり

GETでは、URLに投稿した内容をクエリストリングという形で付与してデータをサーバに送りました。

POSTでは、リクエストメッセージ内のリクエストボディというデータ領域にデータを込めて送ります。

このリクエストメッセージは容量制限が緩く、画像データなどのバイナリデータを込めることが可能です。


続・簡易 BBS の作成

POSTメソッドを使った入力フォーム

落ち穂拾いでは、POSTメソッドを使った入力フォームを作っていきます。

また、「表示」と「投稿」で機能を分けた設計にしていきます。

ここまでのコードは本編の終了時のコードを元に編集していきます。ただし、ファイル名は新規に mojo_post_bbs.pl とします。ファイルをコピーするなどして対応するか、以下のリンクからコードをコピぺしてください。

[GitHub] mojo_post_bbs.pl


続・簡易 BBS の作成

POSTメソッド

まず、テンプレート部にある、既存のフォーム内のボタンを以下のように変更します。

[GitHub] mojo_post_bbs.pl

<form action="/" method="get">
    <input name="body" type="text">
    <input type="submit" value="GETで投稿する"> <!-- ボタン名を変更 -->
</form>

続・簡易 BBS の作成

POSTメソッドフォームを追加する

次に、テンプレート部にPOSTメソッド用の入力フォームを追加します。GETメソッドのフォームとの違いは以下の3つです。

  1. <form> タグのactionが /post になっている
  2. <form> タグのmethodが /post になっている
  3. <form> タグ内のボタンの文字列をPOSTにしている

[GitHub] mojo_post_bbs.pl

    <input type="submit" value="GETで投稿する">
</form>
<!-- 以下の4行追加 -->
<form action="/post" method="post">
    <input name="body" type="text">
    <input type="submit" value="POSTで投稿する">
</form>

続・簡易 BBS の作成

POSTメソッドフォームを追加する

この時点でブラウザをリロードすると、POSTで投稿するフォームとボタンが表示されます。

しかし、POSTの入力欄に入れて「POSTで投稿」ボタンを押しても、エラーが出ます。

これは、テンプレートにある入力フォームがPOSTメソッドで情報を送っても、その情報を受け取るコントローラーがないためです。


続・簡易 BBS の作成

POSTメソッドをコントローラーで受け取る

POSTを受け付けるコントローラーを追加します。 [GitHub] mojo_post_bbs.pl

  $c->render('index');
};
# 以下の6行追加
post '/post' => sub {              # getではなく、post 。また第一引数にも注目
  my $c     = shift;
  my $entry = $c->param('body');
  push @entries , $entry;
  $c->stash( kakikomi => \@entries );
  $c->render('index');
};

追加したコントローラーのメソッドが get ではなく、 post であり、postメソッドの第一引数が /post となっています。それ以外は get メソッドと同じです。


続・簡易 BBS の作成

POSTメソッド実装完了

この時点でPOSTメソッドでの投稿が可能になっています。

GETとPOST、それぞれの方法で投稿して、ブラウザのアドレスバーに表示される内容が異なっていることを確認します。


続・簡易 BBS の作成

GETとPOSTの機能に応じたコード作り

ここからは、さらなる「落ち穂拾い」です。

コントローラー部のgetメソッドとpostメソッドを比較すると、異なっているのはそれぞれのコードリファレンスの最初だけです。

get '/' => sub {
  # 中略
}

post '/post' => sub {
  # 中略
}

続・簡易 BBS の作成

GETとPOSTの復習(再再掲)

また、 GET と POST は利用用途で使い分ける方が好ましいです。GETとPOSTの復習です。

  • GET : (主に)サーバからデータを取得する

  • POST : (主に)サーバにデータを送信する

この、GETとPOSTの原則をコードで再現します。


続・簡易 BBS の作成

GETはデータの取得だけ

コントローラー部にあるgetメソッドから、投稿データを受け取り配列に保存する部分をコメントアウトします。

GET : (主に)サーバからデータを取得する

[GitHub] mojo_post_bbs.pl

get '/' => sub {
  my $c     = shift;
#  my $entry = $c->param('body');    # コメントアウト
#  push @entries , $entry;           # コメントアウト
  $c->stash( kakikomi => \@entries );
  $c->render('index');
};

続・簡易 BBS の作成

GETはデータの取得だけ

先のコメントアウトにより、getメソッドは「サーバから取得したデータの表示」の役割のみになります。

ブラウザでGETの入力欄に入力して「GETで投稿する」ボタンを押しても、投稿は反映されなくなりました。


続・簡易 BBS の作成

POSTはデータの送信だけ

引き続きpostメソッドです。少しだけ複雑です。

POST : (主に)サーバにデータを送信する


続・簡易 BBS の作成

POSTはデータの送信だけ

postメソッドを見ると、以下の二つの機能が原則から外れています。これらはデータの取得と表示のための機能で、POSTの原則である「データの送信」から離れています。これをコメントアウトします。 [GitHub] mojo_post_bbs.pl

  1. テンプレートに投稿(配列リファレンス)を渡すための stash

  2. indexテンプレートを表示する render

post '/post' => sub {
  my $c     = shift;
  my $entry = $c->param('body');
  push @entries , $entry;
  # $c->stash( kakikomi => \@entries );# コメントアウト
  # $c->render('index');               # コメントアウト
};

続・簡易 BBS の作成

POSTはデータの送信だけ

しかし、この時点でブラウザからPOSTで投稿するとタイムアウトしてしまいます。

これは、投稿を保存した後に何を表示するか?という $c->render('index'); も削ってしまったためです。

ここで、投稿した内容を表示しているのは get メソッドであることを思い出し、post の処理が終わったら get に処理を引き渡す1行を追加します。


続・簡易 BBS の作成

redirect_to

postメソッドの処理の最後に、 get '/' へ処理を遷移させる redirect_to メソッドを追加します。

このように書くことで、postの処理が終わった後にコントローラー内の get '/'へと処理が移ります。 [GitHub] mojo_post_bbs.pl

post '/post' => sub {
  my $c     = shift;
  my $entry = $c->param('body');
  push @entries , $entry;
  # $c->stash( kakikomi => \@entries );# コメントアウト
  # $c->render('index');               # コメントアウト
  $c->redirect_to('/'); # 投稿を受け付けた後に、get で / に移動
};

続・簡易 BBS の作成

ここまでの処理の流れ

  1. getでページが表示される
  2. postの入力欄に何かを入力し、「POSTで投稿」ボタンを押す
  3. フォームがコントローラーにpostメソッドで情報を送る
  4. 投稿内容をコントローラーのpostメソッドが受け取る
  5. postメソッドが投稿を配列 @entries に追加する
  6. 処理をgetメソッドに移す
  7. getメソッドは @entries を配列リファレンスにして、stashメソッドに格納する
  8. getでページが表示され、stashで渡された配列リファレンスをテンプレート内で表示する

続・簡易 BBS の作成

GETメソッドのformを削る

POSTがデータの投稿の処理を行うので、GETから投稿の処理を削除します。 [GitHub] mojo_post_bbs.pl

テンプレート内にある、GETメソッドで送信しているformタグを削除します。

<form action="/" method="get">
    <input name="body" type="text">
    <input type="submit" value="GETで投稿する">
</form>

ほかにも、コントローラー部にあるコメントアウトした行もついでに削除します。

ここで保存してブラウザをリロードすると、フォームが一つになっているはずです。


続・簡易 BBS の作成

確認

実際に、投稿ができるか、過去の投稿も表示されるか確認しましょう。

また、投稿時にURLが変わらないことも確認しましょう。

これでおしまいです。お疲れ様でした!