ブログトップ 記事一覧 ログイン 無料ブログ開設

サンプルコードによるPerl入門 〜 Perlで楽しくプログラミングを学ぼう 〜

3000-01-01

サンプルコードによるPerl入門 - 目次からすべての記事が観覧できます

 サンプルコードを中心としたPerlの入門サイトです。応用的な話題もたくさん扱っているので、Perlを詳しく学びたい方にはおすすめのサイトです。サンプルコードによるPerl入門では、現代的なPerlの記述を行うように心がけています。筆者は木本裕紀(きもとゆうき)といいます。

 仕事や学校でPerlを使う初学者の方にぜひサンプルコードによるPerl入門を教えてあげてください。気に入った記事がありましたらはてなブックマークもお願いします。ブックマークボタンとツイートボタンが各記事の右下についています。コメントやトラックバックも受け付けています。

(スマートフォン、タブレットの場合のサンプルコードによるPerl入門のPCサイト表示はこちらから行うことができます)

Perl基礎

 Perlの基礎について解説します。Perlのインストール、基本的な構文、配列、ハッシュ、正規表現、ファイル入出力、オブジェクト指向などを学ぶことができます。


  1. コマンドプロンプト- コマンドプロンプトの使い方
  2. Perlとは - Perlの特徴について
  3. Perlインストール - Perlのインストール方法
  4. Perl基礎文法最速マスター - Perlの基礎をすばやく学習
  5. 現代的なPerlの記述方法 - Perlの現代的な書き方
  6. 実践で役立つPerl正規表現 - Perlの正規表現で頻繁に利用するテクニック
  7. 配列とハッシュを自由に扱う - ハッシュと配列の扱い
  8. サブルーチンの作成 - サブルーチンの作成方法
  9. Perlのスコープを理解する - スコープという概念を学習
  10. ファイル入出力の基礎 - ファイルの読み書き
  11. Perlオブジェクト指向入門 - オブジェクト指向の入門
  12. デバッガの手引き - デバッガの紹介
  13. Perl豆知識 - 知っておくと便利な豆知識
  14. Perl FAQ - Perlでよくある質問に答える

Mojolicious入門

 Mojolicious入門 〜 Perlで楽しくWebアプリケーションを作ろう 〜
Perlを学ぶ楽しい方法のひとつはWebアプリケーションを作成してみることです。Webアプリケーションを作成できれば、自分でWebサービスを公開することもできます。MojoliciousというWebフレームワークを使って、PerlでWebアプリケーションを開発する方法を解説しています。

Perl書籍

 Perl関連の書籍の紹介です。「サンプルコードによるPerl入門基礎編」「簡単プログラミング Perl/CGI」と「もっと自在にサーバを使い倒す 業務に役立つPerl」は僕が書いています。

Perl応用

 基礎を学び終えたら、関数とモジュールについて知るのが、上達の近道です。よく使用する関数や、モジュールについて解説しています。またデータベース操作についても学ぶことができます。

  1. よく使用する関数一覧 - よく使用する関数の紹介
  2. Perlモジュール徹底解説 - モジュールについての詳しい解説
  3. Validator::Customリファレンス - HTMLフォームのバリデーション
  4. SQLiteで学ぶデータベース操作の基礎 - SQLiteとDBIを使ったデータベース操作
  5. DBIx::Customリファレンス - データベースに便利にアクセス
  6. PDLによる統計解析 - PDLモジュールを使った統計解析
  7. Perlその他の情報

Perlリファレンス

Perl逆引き辞典

 逆引き辞典です。やりたいことをさがせます。簡単なサンプルつきです。

コメントデバッグコマンドライン引数配列
ハッシュサブルーチンモジュール数値演算
ビット演算文字列文字コード正規表現
ファイルとディレクトリファイルとディレクトリ(UNIX系OS)ファイル入出力制御構造
変数情報取得日付と時刻開発環境構築
特殊変数プラグマワンライナーPerlとMySQLの連携
自動試験プロセス間通信ソケットオブジェクト指向

Perlその他

CentOS・Red Hat Linux実践テクニック

Perl以外の技術情報

2014-04-16

IOの負荷をかけているプロセスを調べるためのツール piotop

 topコマンドのように、実行中のプロセスとプロセスのreadとwriteのI/OをBpsでリアルタイムで表示するツールpiotopというのがGitHubで公開されています。

-- Every 3 sec --
 13:59:10 up 13 days, 15:28, 11 users,  load average: 0.22, 0.05, 0.01
 pid   state            read         write        command          cwd_path
 1818  S (sleeping)     0bps         1Mbps        kjournald        /
 13314 S (sleeping)     21Kbps       32Kbps       rsync            /backup
 13312 D (disk sleep)   21Mbps       0bps         rsync            /
 13313 D (disk sleep)   20Mbps       0bps         rsync            /backup
 21561 S (sleeping)     0bps         0bps         bash             /root
 1788  S (sleeping)     0bps         0bps         kmpathd/0        /

Linux上でプロセス毎のI/Oを調査するツール piotop.pl をさらに改造

piotop(GitHub)

 Perlのツールなので、Perlのどのバージョンがインストールされているかを気にせずに利用できるので便利です。cpanmを利用するパッチを送って適用してもらったので、セットアップもコマンド一発でできます。

 こういうのが、Perlのもっとも便利な側面なので、みなさんもPerlで、ばしばしアプリケーションを作りましょう。どんな環境でも簡単に使ってもらえるアプリができます。


Perlで作成されているアプリケーション

2014-04-14

テンプレートヘルパー | Mojolicious入門

 テンプレートで利用すると便利なヘルパーについて解説したいと思います。ヘルパーとは、テンプレート内で呼び出すことのできる関数のようなものだと考えてください。layoutヘルパー、stashヘルパーについては、すでに解説していますので、それ以外のヘルパーについて解説します。

スタイルシートの埋め込み

 テンプレートの中にスタイルシートを記述したい場合はstylesheetヘルパーを使用します。beginendで囲った部分にスタイルシートを書きます。

%= stylesheet begin
  body {
    background:blue;
  }
% end

 通常の方法でstyleタグを使って書いてもよいのですが、こちらのほうが簡潔ですし、汎用性のあるタグに展開されるので便利です。以下のようなタグに展開されます。

<style>/*<![CDATA[*/

  body {
    background:blue;
  }

/*]]>*/</style>

 またpublicディレクトリにあるスタイルシートをstylesheetヘルパーで読み込むことができます。

%= stylesheet '/css/common.css';

 これは次のように展開されます。

<link href="/css/common.css" rel="stylesheet" />

JavaScriptの埋め込み

 テンプレートの中にJavaScriptを記述したい場合はstylesheetヘルパーを使用します。beginendで囲った部分にJavaScriptを書きます。

%= javascript begin
  alert('Hello');
% end

 通常の方法でscriptタグを使って書いてもよいのですが、こちらのほうが簡潔ですし、汎用性のあるタグに展開されるので便利です。以下のようなタグに展開されます。

<script>//<![CDATA[

  alert('Hello');

//]]></script>

 またpublicディレクトリにあるJavaScriptをjavascriptヘルパーで読み込むことができます。

%= javascript '/js/common.js';

 これは次のように展開されます。

<script src="/js/common.js"></script>

アプリケーションオブジェクトの取得

 アプリケーションオブジェクトを取得するにはappヘルパーを使用します。

% my $app = app;

コントローラーオブジェクトの取得

 テンプレートの中では$selfという名前で、コントローラーオブジェクトを参照することができます。

% my $c = $self

 これを使って、テンプレートの中でHTTPメソッドを取得することなどができますね。

% my $http_method = $self->req->method;

データのダンプ

 データの内容をダンプするためのdumperメソッドが用意されています。これは機能的にはData::DumperモジュールのDumper関数と同じです。

% warn dumper $date;

他のテンプレートの取り込み

 includeヘルパーを使うと他のテンプレートを取り込むことができます。

%= include '/include/header.html.ep

 ヘッダやフッタなどは、サイトで共通なことが多いですので、これらを作っておいて、複数のテンプレートから読み込むと便利です。includeヘルパー第二引数以降を利用することで、スタッシュの値を設定することができます。

%= include '/include/header.html.ep, name => 'kimoto', age => 34;

URLの表現

 Mojoliciousではアプリケーションの内部的なURLを表現する場合は、パフォーマンスが重要になるアプリケーションを除いてurl_forヘルパーを使用するようにしてください。たとえば「/date/20131215」というURLを表現したい場合は次のように記述します。

<a href="<%= url_for('/date/20131215') %>">2013/12/15</a>

 url_forメソッドを使うのは、アプリケーションに汎用性を持たせるためです。このように記述しておけば、CGIとして起動しても、サーバーとして起動しても、URLが汎用的になります。

 これは次のように展開されます。

# CGIの場合
<a href="/myapp.cgi/date/20131215">2013/12/15</a>

# サーバーとして起動した場合
<a href="/date/20131215">2013/12/15</a>
Mojo::URLオブジェクト

 url_forヘルパーで取得するのはMojo::URLオブジェクトです。Mojo::URLクラスはURLを扱うためのクラスです。

 Mojo::URLオブジェクトを文字列化するためにはto_strongメソッドを使うか、文字列として評価します。

% my $url_str = url_for->to_string;
% my $url_str = "" . url_for;

 最初の例では「<%= %>」の中は、文字列として評価されるために単純に

<%= url_for('/some') %>

 と書くだけで、URLが文字列として展開されます。

現在のURLを取得

 url_forヘルパーで引数を指定しなければ、現在のURLを取得することができます。

% my $current_url = url_for

クエリ文字列

 url_forヘルパーで注意しておきたいのは、引数なしで現在のURLを取得する場合は、クエリ文字列を除いた部分のURLを取得できるということです。もしクエリ文字列を含めたURLを取得したい場合は<string>url_withヘルパーを利用します。

<%= url_with %>

 たとえば「/some?name=kimoto&age=30」というURLをアクセスした場合はurl_forヘルパーでは「/some」を取得しますがurl_withヘルパーであれば「/some?name=kimoto&age=30」を取得できます。

 クエリの部分はMojo::Parametersオブジェクトに保存されています。これはMojo::URLクラスのqueryメソッドで取得できます。

my $query = url_with->query;

 またqueryメソッドは、クエリ文字列を設定する機能もあわせてもっています。クエリ文字列を設定するには以下の三種類の方法があります。最初のクエリ文字列が「title=perl&name=ken」だったと想定してください。

クエリ文字列を置き換える

 クエリ文字列を置き換えるには次のようにリスト形式で渡します。

$url->query(name => 'taro', price => 1900);

 上記の例の場合は以下のように置き換わります。

# 前
title=perl&name=ken

# 後
name=taro&price=1900
クエリ文字列のマージ

 クエリ文字列をマージするには配列のリファレンスとして渡します。

$url->query([name => 'taro', price => 1900]);

 次のようにマージされます。値が同じものは置き換えられます。

# 前
title=perl&name=ken

# 後
title=perl&name=taro&price=1900
クエリ文字列の追加

 クエリ文字列を追加するにはハッシュのリファレンスとして渡します。

$url->query({name => 'taro', price => 1900});

 次のように追加されます。

# 前
title=perl&name=ken

# 後
title=perl&name=ken&name=taro&price=1900

 Webアプリではページ番号だけを差し替えたいという要望が強いと思います。そういう場合は、クエリのマージの機能を使うのがよいでしょう。

<%= url_with->query([page => $page]) %>

テンプレートヘルパーを利用したサンプル

 今回解説したテンプレートヘルパーを使ったサンプルコードを書いてみます。

use Mojolicious::Lite;

get '/person' => sub {
  my $self = shift;
  
  # パラメーター
  my $name = $self->param('name');
  my $age = $self->param('age');
  
  # 描画
  $self->render('index', name => $name, age => $age);
};

app->start;

__DATA__

@@ index.html.ep
<%
  # スタッシュの値
  my $name = stash('name');
  my $age = stash('age');
  
  # ログの取得
  app->log->info('Template Helper');
  
  # HTTPメソッド
  my $http_method = $self->req->http_method;
  
  # データのダンプ
  my $data = [1, 2, 3];
  warn dumper $data;
%>
<html>
  <head>
    <title>Template Helper</title>
    %= stylesheet '/css/common.css';
    %= javascript '/js/common.js';
  </head>
  <body>
    %= include '/include/header';
    
    Name: <%= $name %><br>
    Age: <%= $age %><br>
    Current URL: <%= url_with %><br>
    Current URL with some change: <%= url_with->query([name => 'ken']) %>
    %= include '/include/footer';
  </body>
</html>

public/css/common.css

 CSSファイルを「public」ディレクトリの中に配置しましょう。「public/css/common.css」という名前で保存してください。文字色変更する設定などが書いてあります。

#header h1 {
  color:green;
  border-bottom:1px solid gray;
}

#footer {
  color:red;
  border-top:1px solid gray;
  text-align:center;
}
public/js/common.js

 JavaScriptファイルを「public」ディレクトリの中に配置しましょう。「public/js/common.js」という位置においてください。「Hello」と表示するダイアログを実行するJavaScriptです。

alert('Hello');
ヘッダとフッタ

 ヘッダとフッタを作ってみましょう。「templates」ディレクトリの中に、「templates/include/header.html.ep」と「templates/include/footer.html.ep」という名前で保存してください。

templates/include/header.html.ep

<div id="header">
<h1>Template Helper</h1>
</div>

templates/include/footer.html.ep

<div id="footer">
Author kimoto
</div>
アプリケーションの実行

 このアプリケーションを実行して「/person?name=kimoto&age=32」でアクセスしてみてください。上部にヘッダ、下部フッタが、挿入されています。コンテンツの内容として以下が表示されます。

Name: kimoto
Age: 32
HTTP Method: GET
Current URL: /person?name=kimoto&age=32
Current URL with some change: /person?age=32&name=ken


Mojolicious入門

2014-04-12

ルーティングの基礎 | Mojolicious入門

 次にルーティングについてもう少し詳しく解説します。ルーティングとはURLと処理の対応の記述のことです。

 簡単なルーティングについては、これまでも使ってきました。

get '/' => sub { ... };
get '/info' => sub { ... };
get '/date/:date' => sub { ... };

 ここでは、ルーティングについてもう少し詳しく解説します。

プレースホルダー

 最初にプレースホルダーについて解説します。

通常のプレースホルダー

 先頭にコロンをつけると、その部分はパラメーターとして取得できることは説明しました。

get '/date/:date' => sub {
  my $self = shift;
  my $date = $self->param('date');
};

 Mojoliciousでは、これをプレースホルダーと呼びます。注意してほしいのは、このプレースホルダーは、「/」と「.」以外の値にマッチするということです。

 たとえば「/date/20131015/hello」というURLでアクセスしたとしましょう。これはルーティングが成功しません。ルーティングが成功して「date」に「20131015/hello」を受け取ることができるのではなくって、ルーティング自体が成功せず、ページが見つかりません。

 たとえば「/date/20131015.json」というURLでアクセスしたとしましょう。これはルーティングが成功しません。ルーティングがマッチして「date」に「20131015.json」を受け取ることができるのではなくって、ルーティング自体が成功せず、ページが見つかりません。

 プレースホルダーは「()」を使って、その部分がプレースホルダーであることを区別することもできます。

get '/date/(:date).json' => sub { ... };

 「/date/20130213.json」でアクセスすれば、ルーティングが成功して、パラメーター「date」に「20130213」を受け取ることができます。

リラックスプレースホルダー

 通常のプレースホルダーは「/」と「.」以外にマッチしますが、リラックスプレースホルダーを使えば「.」以外にマッチさせることができます。リラックスプレースホルダーは先頭が「#」ではじまります。

get '/date/#date' => sub { ... };

 「/date/20130213.json」でアクセスすれば、ルーティングが成功して、パラメーター「date」に「20130213.json」を受け取ることができます。「.」を含んだ部分を取得することができます。

 リラックスプレースホルダーはこのように「.」を含んだ部分もパラメーターとして受け取ることができるのが特徴です。

ワイルドカードプレースホルダー

 「/」と「.」を含むすべての文字にマッチさせるにはワイルドカードプレースホルダーを利用します。ワイルドカードプレースホルダーは先頭が「*」で始まります。

get '/date/*date' => sub { ... };

 「/date/20130213/hello」でアクセスすれば、ルーティングが成功して、パラメーター「date」に「20130213/hello」を受け取ることができます。「/」を含んだ部分を取得することができます。

 ワイルドカードプレースホルダーはこのように「/」を含んだ部分もパラメーターとして受け取ることができるのが特徴です。

HTTPメソッド

 次にHTTPメソッドについて解説したいと思います。HTTPメソッドというのは、HTTPリクエストを送信するときに指定するものです。一般的な用法であれば、ページの内容を取得するときはGETメソッド、フォームなどでデータを送信するときはPOSTメソッド、ページの存在を確認したい場合はHEADメソッドが使用されます。

メソッド名用法
GETページの内容を取得
POSTフォームなどでデータを送信
HEADページの存在を確認

 他にもPUTメソッドやDELETEメソッドやPATCHメソッドなどがありますが、ここではこの三つを覚えてください。特にGETとPOSTを覚えておけばWebサイトの作成に困ることはありません。

 Mojolicious::Liteでは上記のHTTPメソッドに対応して以下の関数が利用できます。

get '/' => sub { ... };
post '/' => sub { ... };
head '/' => sub { ... };
put '/' => sub { ... };
del '/' => sub { ... };
patch '/' => sub { ... };
すべてのHTTPメソッドにマッチさせる

 同じURLでgetとpostの両方を受けたいという場合は多いと思います。そのような場合はany関数を使いましょう。すべてのHTTPメソッドにマッチします。

any '/' => sub { ... };
HTTPメソッド名を取得する

 any関数で受け取った場合は、ユーザーがどのHTTPメソッドでアクセスしてきたのかを知りたい場合があると思います。そのような場合はreqメソッドでHTTPリクエストを表現するMojo::Message::Requestオブジェクトを取得して、methodメソッドでHTTPメソッドを取得できます。

my $http_method = $c->req->method;

ページが見つからない場合を自分で処理する

 日付の場合は、たとえば、数値の8桁でなければ、ページが見つからないという処理を書きたいと考えると思います。数値の8桁以外の場合は、意味を持たないからです。このような場合は、存在しないということを知らせるのがよいでしょう。render_not_foundメソッドを使ってページが「404 Not Found」を自分で描画することができます。

get '/date/:date' => sub {
  my $self = shift;
  my $date = $self->param('date');
  
  # 日付の形式でない場合は「404 Not Found」を描画する
  unless ($date =~ /^[0-9]{8}$/) {
    $self->render_not_found;
    return;
  }

  $self->render('date', date => $date);
};

 render_exceptionメソッドを代わりに使えば、エラーを示す「500 エラーメッセージ」を表示することもできます。

$c->render_exception('Error');

すべてのルーティングに共通する前処理

 すべてのルーティングに共通する前処理を書きたいと思うことがあると思います。たとえば、ログインしていなければ「/login」というページに、リダイレクトしたい場合があると思います。

 このような場合はunder関数を使えば、すべてのルーティングに共通する前処理を書くことができます。以下のサンプルではunder関数に渡したサブルーチンの中でスタッシュの値を取得して、それをふたつの異なるルーティング「/some1」と「some2」で利用できることを示しています。

use Mojolicious::Lite;

# 前処理
under sub {
  my $self = shift;
  
  $self->stash('name' => 'Kimoto');

  return 1;
};

get '/some1' => sub { 
  my $self = shift;

  my $name = $self->stash('name');

  $self->render(text => $name);
};

get '/some2' => sub { 
  my $self = shift;

  my $name = $self->stash('name');

  $self->render(text => $name);
};

app->start;

 上記のサンプルではunder関数の中で「return 1」として1を返していますが、これは後に続く継続の処理を行いたい場合に必要です。underの後に続く継続の処理を行いたくない場合は「return」と書いて、未定義値を返却してください。

 以下のようにunderを変更すると、継続の処理が行わずに画面に「Access deny」と表示されるのが確認できます。

under sub {
  my $self = shift;
  
  my $continue = 0;
  
  # 継続処理を行わない場合
  unless ($continue) {
    $self->render(text => 'Access deny');
    return;
  }

  return 1;
};

ルーティングのサンプル

 ルーティングを理解するためのサンプルコードを書いてみます。

use Mojolicious::Lite;

# 前処理
under sub {
  my $self = shift;
  
  # ユーザーがadminの場合は許可しない
  my $user = $self->url_for->path->parts->[0] // '';
  if ($user eq 'admin') {
    
    $self->res->code(403);
    $self->render(text => 'Forbidden');
    return
  }
  
  return 1;
};

# /ユーザー名/プロジェクト名/ディレクトリ名
# あるいは /ユーザー名/プロジェクト名
get '/:user/:project/*dir' => {dir => undef} => sub {
  my $self = shift;
  
  # パラメーター
  my $user = $self->param('user');
  my $project = $self->param('project');
  my $dir = $self->param('dir') // 'Nothing';
  
  # 描画
  $self->render(
    'index',
    user => $user,
    project => $project,
    dir => $dir
  );
};

any '/http-method' => sub {
  my $self = shift;

  # HTTPメソッドの取得
  my $http_method = $self->req->method;

  $self->render(text => "HTTP Method: $http_method");
};

app->start;

__DATA__

@@ index.html.ep
<%
  my $user = stash('user');
  my $project = stash('project');
  my $dir = stash('dir');
%>
<html>
  <head>
    <title>Routing</title>
  </head>
  <body>
    User: <%= $user %><br>
    Project: <%= $project %><br>
    Directory: <%= $dir %></br>
  </body>
</html>
アプリケーションの解説

 このアプリケーションは次のURLでアクセスできるようになっています。

/ユーザー名/プロジェクト名/ディレクトリ名
/ユーザー名/プロジェクト名

 「/kimoto/dog/dir1/readme.txt」でアクセスすれば、次のように表示されます。

User: kimoto
Project: dog
Directory: dir1/readme.txt

 「/kimoto/dog」でアクセスすれば、次のように表示されます。

User: kimoto
Project: dog
Directory: Nothing

 これは次のようにルーティングを定義しているからです。

get '/:user/:project/*dir' => {dir => undef} => sub { ... };

 また「/admin/dog/dir1/readme.txt」でアクセスすれば、「Forbidden」と表示されます。これは以下の前処理を記述しているためです。

# 前処理
under sub {
  my $self = shift;
  
  # ユーザーがadminの場合は許可しない
  my $user = $self->url_for->path->parts->[0] // '';
  if ($user eq 'admin') {
    
    $self->res->code(403);
    $self->render(text => 'Forbidden');
    return
  }
  
  return 1;
};

 URLのパスの最初の部分が「admin」の場合は、ステータスコードを「403」に設定して「Forbidden」というテキストを返却しているようにしています。

 少し解説します。

# URLのパスの最初の部分を取得
my $user = $self->url_for->path->parts->[0] // '';

 まずアクセスしたURLを取得するにはurl_forメソッドを使用します。取得するのはMojo::URLオブジェクトです。次のこのURLのパスの部分を取得するには、Mojo::URLクラスのpathメソッドを使用します。取得するのはMojo::Pathオブジェクトです。次にパスの各部分は配列として保存されていて、これはMojo::Pathクラスのpartsメソッドによって取得できます。

 「//」は、左辺が未定義値だった場合に、右辺を代入できるperlの「defined-or演算子」です。

 このようにしてURLのパスの最初の部分を取得しています。

 次にユーザーにチェックの部分です。

# ユーザーがadminであれば、ステータスコードに403を設定して、Forbiddenを表示
if ($user eq 'admin') {
  
  $self->res->code(403);
  $self->render(text => 'Forbidden');
  return
}

 コントローラークラスのresメソッドを使用すればレスポンスオブジェクトを取得できます。これはMojo::Message::Responseオブジェクトです。Mojo::Message::Responseクラスのcodeメソッドを使用すれば、ステータスコードを設定できます。

 次の部分ではHTTPメソッド名を取得しています。

# HTTPメソッドの取得
my $http_method = $self->req->method;

 「/http-method」にアクセスすると「HTTP Method: GET」と表示されます。


Mojolicious入門

2014-04-09

アプリケーションとコントローラーの機能 | Mojolicious入門

 MojoliciousはWebアプリケーションを作る為の便利な機能をたくさん持っています。その中でも、使用頻度が高いものを紹介したいと思います。最初にこれらを覚えておけば、どうしたらいいかを迷わなくてすむと思います。

アプリケーションオブジェクト

 アプリケーションの本体を表すオブジェクトをapp関数で取得することができます。app関数はMojolicious::Liteを読み込んだときに、自動的にインポートされます。

use Mojolicious::Lite;

# アプリケーションオブジェクト
my $app = app;

 アプリケーションオブジェクトはMojoliciousクラスに属しており、Mojoliciousクラスのメソッドを呼び出すことができます。メソッドの一覧についてはMojolicious API リファレンスを参考にしてください。

ホームオブジェクト

 まずMojoliciousのホームディレクトリを表現するhomeオブジェクトを、homeメソッドを使って取得することができます。ホームオブジェクトは、Mojo::Homeクラスに属します。

# ホームオブジェクトの取得
my $home = $app->home;

 ホームオブジェクトからは、Mojo::Homeクラスのメソッドを呼び出すことができます。Mojo::Homeはrel_fileというメソッドを持っており、ホームディレクトリからの相対パスで指定したパスを絶対パスに変換してくれます。

my $path_abs = $home->rel_file('db/myapp.db');

 これは、データベースファイルなどのパスを取得するときに便利です。

ログファイル

 Mojoliciousはログを出力する機構を備えています。アプリケーションと同じディレクトリにlogというディレクトリを作成してみてください。

myapp.pl
log

 するとこのディレクトリの中にdevelopment.logというファイルが作成され、ここにアプリケーションのログが出力されます。

log/development.log

 このログファイルに自分で出力することもできますが、そのためにはアプリケーションオブジェクトからlogメソッドを使って、ログオブジェクトを取得します。

my $log = $app->log;

 ログオブジェクトはMojo::Logクラスに属しています。Mojo::Logクラスは、レベルに応じたログの出力を行うことができます。以下のメソッドを使ってレベルに応じてログを出力することができます。

$log->debug($messgae);
$log->info($messgae);
$log->warn($messgae);
$log->error($messgae);
$log->fatal($messgae);

 デバッグのときだけ出力したい情報はdebugで出力します。通常はinfoメソッドで情報を出力して、警告、エラー、致命的なエラーの場合にはwarnメソッド、errorメソッド、fatalメソッドを利用するとよいでしょう。

 何がエラーで、何が警告なのかは、プログラマである各自が判断して決めます。

設定ファイル

 Mojoliciousでは設定ファイルを簡単に記述することができます。スクリプトと同じディレクトリに、スクリプトと同じ名前で拡張子がconfのファイルを作成してください。

myapp.pl
myapp.conf

 この設定ファイルはPerlで記述することができます。

{
  name => 'kimoto',
  age => 19
}

 ハッシュリファレンスを記述することに注意してください。また日本語を利用する場合は、ファイルはUTF-8で保存してください。

設定ファイルの読み込み

 設定ファイルの読み込みは、Configプラグインを利用することで読み込みます。プラグインとは、Mojoliciousの機能を追加する仕組みのことで、Configプラグインは、設定ファイルを読み込むために最初から容易されているプラグインです。

 プラグインを利用するにはplugin関数またはアプリケーションオブジェクトからpluginメソッドを呼び出します。

plugin('Config');
$app->plugin('Config');

 これで、設定ファイルが読みこまれ、configメソッドで設定を取得することができます。

# ひとつづつ取得
my $name = $app->config('name');
my $age = $app->config('age');

# 全部を取得
my $config = $app->config;

 またアプリケーション上で設定を行うことも可能です。

# 設定
$app->config('name' => 'Ken');

コントローラーでアプリケーションオブジェクトを取得

 コントローラーからアプリケーションオブジェクトを取得するには、コントローラーオブジェクトからappメソッドを利用します。

my $app = $c->app;

 たとえば、以下のように取得できます。アプリケーションオブジェクトを取得できれば、ここからhomelogを呼び出すこともできますね。

get '/' => sub {
  my $self = shift;

  my $app = $self->app;
  $app->log->info('Info');
};

静的ファイルの配置

 CSSやJavaScriptや画像などの静的なファイルを利用したい場合は、アプリケーションと同じディレクトリにpublicディレクトリを作成します。

myapp.pl
public

 そしてこの中にCSSなどの静的ファイルを配置します。

public/css/common.css
public/js/common.js

 静的ファイルはMojoliciousによって自動的にディスパッチされます。次のURLでアクセスすると、これらのファイルを取得できます。

http://localhost:3000/css/common.css
http://localhost:3000/js/common.js

テンプレートの外部ファイル化

 Mojolicious::Liteではテンプレートをひとつのファイルの中に書いていましたが、アプリケーションが大きくなってきたときには、外部のファイルに書きたくなってくると思います。

 次のアプリケーションを見てください。

use Mojolicious::Lite;

get '/' => sub {
  my $self = shift;

  $self->render('info');
};

app->start;

__DATA__

@@ info.html.ep
Information

 info.html.epはデータセクションに書かれていますが、このテンプレートを外部ファイル化してみましょう。

 まずスクリプトと同じディレクトリにtemplatesというディレクトリを作成します。

myapp.pl
templates

 この中に、テンプレートファイルを配置します。

templates/info.html.ep

 そして、データセクションは削除してしまいます。

use Mojolicious::Lite;

get '/' => sub {
  my $self = shift;

  $self->render('info');
};

app->start;

 このようにテンプレートファイルを外部化すると、文法のエラーが発生した行番号などがわかりやすくなるので、便利です。

リダイレクト

 リダイレクトとは、他のURLに転送する機能のことです。Mojolicious::Controllerクラスのredirect_toメソッドを使うとリダイレクトを行うことができます。

$c->redirect_to('/other');

これらの機能を使ったサンプル

 では最後に、ここで紹介した機能を使ったサンプルを作成してみます。

myapp.pl

 最初にアプリケーションの本体を記述します。

use Mojolicious::Lite;

# 設定ファイルの読み込み
plugin('Config');

# ログへの出力
app->log->info('Start application');

# データベースファイルのパスを取得
my $db_file = app->home->rel_file('db/myapp.db');

# / へのアクセス
get '/' => sub {
  my $self = shift;

  # アプリケーション
  my $app = $self->app;

  # ログへ出力
  $app->log->info('Access infomation');
  
  # データベースファイルのパスを取得
  my $db_file = $app->home->rel_file('db/myapp.db');

  # 設定ファイルから取得
  my $name = $app->config('name');
  my $age = $app->config('age');

  # テンプレートの描画
  $self->render(
    'info',
    name => $name,
    age => $age,
    db_file => $db_file
  );
};

# リダイレクト
get '/some' => sub {
  my $self = shift;

  $self->redirect_to('/other');
};

get '/other' => sub {
  my $self = shift;

  $self->render(text => 'Other');
};

app->start;

log

 ログファイルのためのlogディレクトリを作成してください。

myapp.conf

 設定ファイルです。myapp.plと同じディレクトリに配置します。

{
  name => 'Kimoto',
  age => 32
}
public/css/common.css

 スタイルシートです。publicディレクトリを作成してその中に配置します。

body {
  background:#FFFFEE;
}
templates/info.html.ep

 テンプレートファイルです。templatesディレクトリを作成してその中に配置します。

<%
  my $name = stash('name');
  my $age = stash('age');
  my $db_file = stash('db_file');
%>

<html>
  <head>
    <title>Information</title>
    %= stylesheet '/css/common';
  </head>
  <body>
    <b>Name</b>: <%= $name %><br>
    <b>Age</b>: <%= $age %><br>
    <b>Database file</b>: <%= $db_file %><br>
  </body>
</html>

 stylesheet関数はここでは解説していませんが、スタイルシートを読み込むためのテンプレートのヘルパーです。

アプリケーションの実行

 ディレクトリ構成が以下のようになっているかを確認してください。

myapp.pl
myapp.conf
templates/info.html.ep
public/css/common.css
log

 アプリケーションを実行して「/」にアクセスすれば、次のような結果を得ることができます。

Name: Kimoto
Age: 32
Database file: /home/kimoto/labo/db/myapp.db

 「/some」にアクセスすれば「/other」にリダイレクトされて、「/other」の内容が表示されます。

Other


Mojolicious入門