Skip to content
This repository has been archived by the owner on May 18, 2022. It is now read-only.
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time

Perl入学式

第5回 Webアプリ編


諸注意

  • 会場について
    • 飲食・喫煙・トイレetc
  • 写真撮影について
    • 写真撮影NGな方はお手数ですが申し出てください

紹介

  • 講師・サポーター紹介

本日の内容

Mojolicious を使って Web アプリケーションを作ろう!

  • Mojolicious の準備
  • HTTP の基礎
  • Mojolicious 入門
  • 簡易 BBS の作成

皆さんで自己紹介


Mojolicious の準備


Mojolicious のインストール

$ cpanm -n Mojolicious
  • エラーになる場合は以下のコマンドを試してみてください。
$ curl -L https://cpanmin.us | perl - -n Mojolicious
  • https://がエラーになる場合はhttp://でも問題ありません。

Mojolicious とは?

  • Perl の Web アプリケーションフレームワーク(WAF)です。
  • MVCフレームワークの、Modelを除いた(ViewとControllerの)機能を持っています。
  • Perl 5.10.1 以降で動作します。

Mojoliciousの資料


HTTP の基礎


HTTPとは?

  • HyperText Transfer Protocolのことです。
  • Web ブラウザと Web サーバの間でコンテンツの送受信を行うための通信手順(プロトコル)です。

HTTP のメソッド

よく使うのは以下の2つです。

GET

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

POST

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

Mojolicious の ひな形


最初に

  • この入門では、難しい表現を避けるために、厳密には正しくない事も書いてあります。
  • この入門に書いていない沢山の引数やコマンドについては、本家サイトなどのリファレンスをご覧ください。

ひな形を作る

$ mojo generate lite_app hello.pl
  • Mojoliciousをインストールすると、mojoというコマンドが使えるようになります。
  • mojo generate lite_appと入力すると、Mojolicious::Liteを使ったひな形を作成してくれます。
  • hello.plは作成するファイル名です。
  • 現在のディレクトリにhello.plというファイルが作成されているか確認して下さい。

起動してみる

$ morbo hello.pl
  • Mojoliciousをインストールすると、morboというコマンドも使えるようになります。
  • morboは開発用のアプリケーションサーバーを起動してくれます。
  • 画面上にServer available at http://127.0.0.1:3000.と表示されれば起動しています。
  • Web ブラウザで http://127.0.0.1:3000 にアクセスしてみましょう。

コード解説

  • 勉強会では、ひな形のソースコードの解説については省略します。

コード解説(Line 1 - 2)

#!/usr/bin/env perl
use Mojolicious::Lite;
  • Mojolicious::LiteMojolicious を簡単に使うためのモジュールです。
  • use Mojolicious::Lite; とすることで、自動的にstrictwarningsutf8Perl 5.10 featureが有効になります。

コード解説(Line 1 - 2)

use strict;
use warnings;
use utf8;
use feature ':5.10';
  • つまり、use Mojolicious::Lite;を書くだけで、ついでに上記のように書いているのと同じということです。

コード解説(Line 4 - 5)

# Documentation browser under "/perldoc"
plugin 'PODRenderer';
  • Mojoliciousでは、機能を拡張するプラグインが利用できます。
  • ここでは、Mojolicious::Plugin::PODRendererを使用しています。
  • http://127.0.0.1:3000/perldocにアクセスするとMojoliciousのPODを読むことができます。
  • [参考資料]

コード解説(Line 7 - 10)

get '/' => sub {
  my $self = shift;
  $self->render(template => 'index');
};
  • ウェブアプリケーションでは、URLごとに処理を変更できると便利です。
  • このようなURLごとに処理を振り分ける機能のことをrouterdispatcherと呼びます。
  • Mojolicious::Liteでは、HTTPのGETリクエスト用のrouterとしてgetという関数が用意されています。

コード解説(Line 7 - 10)

get '/' => sub { ... };
  • 見慣れない書き方ですが、これは、getという関数に、2つの引数を渡しているだけです。
  • 一つ目の引数が'/'という文字列、二つ目の引数がコードリファレンスです。
  • このように書くことで、HTTPのGETメソッドで/にアクセスした時の処理をsub { ... }に書くことができます。

コード解説(Line 7 - 10)

my $self = shift;
$self->render(template => 'index');
  • コードリファレンスの最初の行は、フレームワークのコントローラーを受け取っています。
  • コントローラーにはrenderというメソッドがあり、どのような出力をするのかを書くことができます。
  • ここではindexのテンプレートを使用して出力するように書いています。

コード解説(Line 12)

app->start;
  • Mojolicious::Liteを使う場合は、コードの最後にこの命令文を書かなければいけません。

  • 当面は「お約束」として覚えておけばよいでしょう。


コード解説(Line 13)

__DATA__
  • __DATA__以降は文字通りデータとして使えます。Mojolicious::Liteでは、ここにテンプレートなどを書いておくことができます。

コード解説(Line 15)

@@ index.html.ep
  • Mojolicious::Liteでは、@@ index.html.epと書いておくと、次に@@が出てくるまでの範囲をindex.html.epというファイルとして扱うことができます。このようにすれば、多くのファイルを必要とせずにプログラムを書くことができます。
  • epは、Mojoliciousの標準的なテンプレート機能を使用するための拡張子です。拡張子をepにすることで、テンプレートであることを示します。

コード解説(Line 16 - 18)

% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!
  • %は、その行をPerlのコードとして実行したい時に書きます。ここでは出てきませんがHTMLタグのように<% Perlのコード... %>と書くこともできます。
  • Mojoliciousの標準的なテンプレートでは、このように書くとテンプレートの中でPerlのコードが実行できます。
  • なお、%では、その行全体がPerlのコードとして扱われますが、<% ... %>の場合は、...の部分のみがPerlのコードとして扱われます。

コード解説(Line 16 - 18)

  • layoutはレイアウトを指定します。ここではdefaultを指定しています。(後ほど詳しく説明します)
  • titleはタイトルを指定します。ここではWelcomeを指定しています。(後ほど詳しく説明します)
  • それ以外の通常の文字列は、そのままHTMLとして表示されます。

コード解説(Line 20)

@@ layouts/default.html.ep
  • @@が書いてあるので、これ以降はlayouts/default.html.epとして扱われます。この文字列はパス扱いなので、layoutsディレクトリにあるdefault.html.epというファイルを示します。
  • Mojolicious::Liteでは、layoutsディレクトリ内にレイアウト用のテンプレートを用意でき、layoutコマンドで切り替えて使うことができます。
  • 先のコードで% layout 'default';と指定しましたので、layoutsディレクトリにあるdefault.html.epをレイアウトとして使用することになります。

コード解説(Line 21 - 25)

<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>
  • <%= ... %>(あるいは%=から始まる行)は、Perlのコードを実行するだけでなく、値を表示したい時に書きます。
  • <%= title %>は、先のコードで% title 'Welcome';と指定したので、Welcomeと表示されます。
  • titleは、テンプレート内で使える関数で、このようにHTMLファイルのタイトルを取得したり設定したりできる、便利な関数です。
  • contentは、レイアウトテンプレート内で使える関数で、通常のテンプレートの中身を取得する関数です。

Mojolicious 入門


変数を渡す

get '/' => sub {
  my $self = shift;
  $self->stash(title => 'Hello');
  $self->render('index');
};
% title 'Welcome'; # => 削除する
  • $self->stash で, テンプレート内の変数に変数を渡せる

練習問題

@@ profile.html.ep
<html>
<head><title><%= $name %>のプロフィール</title></head>
<body style='padding: 30px;'>
  私の名前は<%= $name %>です.<br>
  趣味は<%= $hobby %>で, 好きなプログラミング言語は<%= $language %>です.
</body>
</html>
  • このようなテンプレートを用意し, stash で name, hobby, language 変数に値を代入し, 自己紹介ページを作成しよう
    • render で profile テンプレートを指定しましょう

テンプレートの中の特殊記号

% if ($num1 == 1 ) { # %
%= 'hoge';    # %=
    <% if ($num2 == 1 ) { %> # <% ... %>
        <%= $hoge %>         # <%= ... %>
    <% } %>
% }
  • %のように, テンプレートの中で特別な意味を持つ記号がある

テンプレートの中の特殊記号

% if ($num1 == 1 ) { # %
    ...
% }
  • %が先頭にある行は, その後ろのPerlのコードを実行する

テンプレートの中の特殊記号

%= 'hoge';    # %=
  • %=が先頭にある行は, その後ろのPerlのコードを実行して, その結果をテンプレート内に直接埋め込む
    • 返り値を出力するので, print 'hoge';と書いてしまうと1になる!
    • printの実行結果は1なので...

テンプレートの中の特殊記号

<% if ($num2 == 1 ) { %> # <% ... %>
    <%= $hoge %>         # <%= ... %>
<% } %>
  • <% ... %>, <%= ... %>は, それぞれ%, %=をHTMLタグやテキストの中で使えるようにしたもの

練習問題

  • fizzbuzzテンプレートを用意して, 1から100までのfizzbuzzを表示してみましょう
    • 但し, fizzbuzzの処理は全てfizzbuzzテンプレートの中に書くようにしましょう
  • fizzbuzz
    • 3で割り切れる場合「Fizz」
    • 5で割り切れる場合「Buzz」
    • 3でも5でも割り切れる場合「fizzbuzz」
    • いずれも満たさない場合「その数をそのまま」

簡易 BBS の作成


雛形を作る

$ mojo generate lite_app BBS

PODRenderer

# Documentation browser under "/perldoc" # 削除
plugin 'PODRenderer'; # 削除
  • PODRenderer は Mojolicious のプラグインで, perldoc を見れるようにするもの
  • 削除する前に、localhost:3000/perldoc にアクセスしてみよう!

FORM 作成

Welcome to the Mojolicious real-time web framework! # 削除
  • index テンプレートにある, もともとの文字列を削除する

FORM 作成

%= form_for '/' => begin
  %= text_field 'body'
  %= submit_button '投稿する'
% end
  • 削除したところに, フォームを出力するコードを書く
    • form_for, text_field, submit_buttonなどは, Mojolicious のhelperという機能で定義されたPerlの関数(サブルーチン)

FORM 作成

  • ここまで出来たら, 保存してから, ブラウザをリロード (あるいはhttp://localhost:3000にアクセス) してみましょう
  • フォームから投稿しても画面上は何も変わりません
    • 次に, フォームから投稿された文字列を画面に表示するようにしてみよう

GET

  %= submit_button '投稿する'
% end
<p><%= $entry %></p>
  • まずは index テンプレートを上記のように変更する
  • <%= $entry %> は, テンプレート内の変数

GET

get '/' => sub {
  my $self = shift;
  my $entry = $self->param('body'); # 追加
  $self->render('index');
};
  • form の情報を取得するために, 上記のように 1 行追加する
  • $self->param('body') は フォームから投稿した body という名前の値を取得する

GET

get '/' => sub {
  my $self = shift;
  my $entry = $self->param('body');
  $self->stash(entry => $entry); # 追加
  $self->render('index');
};
  • 取得した情報をテンプレートに渡すため, $self->stash(entry => $entry) を挿入する
  • entry に変数 $entry を渡したので, テンプレートで $entry が使用可能になる

GET

  • ここまで出来たら, 保存してからブラウザをリロード (あるいはhttp://localhost:3000にアクセス) してみよう
  • フォームに文字を入力して, 「投稿する」ボタンをクリックしてみよう!

POST

  • 先ほどのフォームは, HTTP でいうところのGETメソッドを利用してデータを送信していました
  • GET でのリクエストは文字数の制限(おおよそ 2KB 程度)があるので、掲示板のような多くのデータを送信する必要がある場合は適当ではありません
    • このような場合, POST によるリクエストを行うとよいです

POST

@@ post.html.ep # 新しいテンプレートを用意する
% layout 'default';
% title '出力'; # タイトルを変更
%= form_for '/post' => method => 'POST' => begin # 投稿先などを変更
  %= text_field 'body'
  %= submit_button '投稿する'
% end
<p><%= $entry %></p>
  • index.html.ep の部分をコピーして, post.html.ep というテンプレートを作成する
  • form_for に書いた method => 'POST' で, get ではなく post で送信するようになる

POST

@@ index.html.ep
% layout 'default';
% title '入力フォーム'; # タイトルを変更
%= form_for '/post' => method => 'POST' => begin # 投稿先などを変更
  %= text_field 'body'
  %= submit_button '投稿する'
% end
  • @@ index.html.ep では, $entry を表示させないようにする
  • その他, メソッドやタイトルも変更しておこう

POST

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

post '/post' => sub {
  my $self = shift;
  my $entry = $self->param('body');
  $self->stash(entry => $entry);
  $self->render('post');
};
  • perl コードも変更しよう
    • 細々とした違いに注意!

POST

  • ここまで出来たら, 保存してから, ブラウザをリロード (あるいはhttp://localhost:3000にアクセス) してみよう
  • フォームに長い文字を入力して, 「投稿する」ボタンをクリックしてみよう!

記事を蓄える

  • 記事を蓄えるための方法としては, いくつかの方法がある
    • DB (データベース) を利用
    • 外部ファイルに書き込み保存
  • 今回は時間の制約上, データを蓄える方法として, 配列を用いる
    • 言うまでもなく, 配列は Web アプリケーションが停止した時点で全てのデータが消えるので, 現実的ではない!
    • MySQLSQLiteなどのデータベースを使うのがオススメです

記事を蓄える

@@ index.html.ep
% layout 'default';
% title '入力フォーム';
%= form_for '/post' => method => 'POST' => begin
  %= text_field 'body'
  %= submit_button '投稿する'
% end
% for my $entry (@{$entries}) {
    <p><%= $entry %></p>
% }
  • テンプレートに, 投稿済みの記事( $entries に格納されている )を表示するよう変更を加える

記事を蓄える

my @entries = (); # 空の配列を宣言
get '/' => sub {
  my $self = shift;
  $self->stash(entries => \@entries); # 配列のリファレンスをテンプレートに渡す
  $self->render('index');
};

post '/post' => sub {
  my $self = shift;
  my $entry = $self->param('body');
  push @entries, $entry; # 配列に格納
  $self->stash(entry => $entry);
  $self->render('post');
};

記事を蓄える

  • ここまで出来たら, 保存してから, ブラウザをリロード (あるいはhttp://localhost:3000にアクセス) してみよう
  • 文字の投稿をいくつか繰り返した後に, http://localhost:3000にアクセスしてみよう!

リダイレクト

  • 別のページへ遷移(移動)するための機能
    • 今回の場合, /postで記事を投稿した後に記事を表示するページである/に戻るようにする
  • Mojolicious ビルトインの redirect_to を使用すればよい

redirect_to

post '/post' => sub {
  my $self = shift;
  my $entry = $self->param('body');
  push @entries, $entry;
                           # '/'へ移る為、'post'へのstash は不要となるので削除
  $self->redirect_to('/'); # 追加
};
  • redirect_to を利用して, /へのページ遷移を追加する
    • postのテンプレートはもう必要ないので, 削除しても問題ない

最終問題

  • これまで作成してきた簡易 BBS を, 改造してみましょう!
  • 例えば...?
    • 名前/メールアドレスを入力/表示できるようにする...
    • メールアドレスが「age」であれば, 記事をpushではなくunshiftする...
    • テンプレートを整理して, 見た目を綺麗にする...
      • Twitter Bootstrapを使ってみる...

まとめ

  • 非常に簡単ではありますが, BBS (のような) Web サービスを開発してみました
    • 時間の制約上, 紹介できなかった部分 (適切な記事の蓄え方など...) は紹介できませんでしたが, Perl を使った Web サービスの開発の基本的な流れは, このようになっています
    • 今日ここまで紹介してきた内容は, 基礎中の基礎です. 「 Web サービスを作ろう!」となると, やはりまだまだ挑戦しなければならない「壁」はいくつもあります
  • その時困ったら, Perl入学式の資料や, スタッフを是非頼って下さい!

質問タイム


お疲れさまでした