Perl入門ゼミ

テキスト処理、Linuxサーバー管理、Web開発ならPerl
  1. Perl
  2. Mojolicious

Mojoliciousのユーティリティ

Mojoliciousのユーティリティを紹介します。

継承を行う

継承を行う場合はbaseモジュールで行うことができますが、少し機能を拡張した継承の方法がMojoliciousには用意されています。機能を拡張した継承を行うには、Mojo::Baseのインポート機能を利用します。

package MyApp::Photoshoot;
use Mojo::Base 'Mojolicious::Controller';

上記の記述はMojolicious::Controllerクラスを継承して、MyApp::Photoshootクラスを作成している例です。

Mojo::Baseの継承機能は以下のような追加の機能を提供します。

  • 「use strict」を自動で行う
  • 「use warnings」を自動で行う
  • 属性を定義するhasメソッドがインポートされる

アクセッサを定義する

アクセッサを定義するにはMojo::Baseクラスのattrメソッドを使用するか、Mojo::Baseの継承機能によってインポートされるhas関数を使用します。アクセッサにはデフォルト値を設定することもできます。

Mojolicious::Liteの場合はアプリケーションオブジェクトからattrメソッドを呼ぶことでアプリケーションクラスに属性を追加することができます。

# Mojolicious::Lite
app->attr(x => 1);

# アクセッサ
my $x = app->x;
app->x(3);

Mojoliciousの場合はMojo::Baseに継承機能によってインポートされるhas関数を使用します。

# Mojolciious

has x => 1;

sub startup {
    my $self = shift;
    
    # アクセッサ
    my $x = $self->x;
    $self->x(3);
}

デフォルト値に関する注意点

デフォルト値が数値と文字列など定数以外の場合は、サブルーチンのリファレンスの戻り値として与える必要があります。これは他のオブジェクトと値を共有しないために必要になるものです。

app->attr(nums => sub { [1, 2, 3] });
app->attr(person => sub { {name => 'Ken', age => 19} });
app->attr(dbh => sub { DBI->connect(...) });

モードを取得・設定する

モードを取得・設定するにはMojoliciousクラスのmodeメソッドを使用します。

# 使い方
my $mode = $app->mode;
$app->mode('test');

# Mojolicious::Lite
app->mode;

# Mojolicious(from Controller)
$self->app->mode;

デフォルトのモードはdevelopmentです。hypnotoadでアプリケーションを実行したときはモードはproductionになります。

環境変数を使ってモードを設定することもできます。

export MOJO_MODE=test

アプリケーションクラスの説明

Webアプリケーションの本体を表すクラスについて解説しておきます。ここからの解説ではWebアプリケーション本体を表すクラスをアプリケーションクラスと呼ぶことにします。

アプリケーションクラス

アプリケーションクラスについて理解するためにソースコードを見てみましょう。アプリケーション名はSampleappでです。

package Sampleapp;
use Mojo::Base 'Mojolicious';

# This method will run once at server start
sub startup {
  my $self = shift;

  # Routes
  my $r = $self->routes;
  $r->get('/')->to('main#default');
}

1;

最初に注目して欲しいのは次の部分です。Mojo::Baseを使うと、クラスを継承することができます。

use Mojo::Base 'Mojolicious';

アプリケーションクラスはMojoliciousというクラスを継承して作成されています。つまりMojoliciousで定義されているメソッドをSampleappですべて使用することができるということです。

またMojoliciousはMojoを継承していますのでSampleappはMojoで定義されているメソッドをすべて利用することができます。

アプリケーションの設定 startup

Sampleappの中にはstartupというメソッドが定義されています。このメソッドはアプリケーションが初期化されるときに一回だけ呼ばれます。ですのでアプリケーションに関する設定はこのメソッドの中で行うことになります。ディスパッチの定義などをstartupメソッドに書くことになります。

sub startup {
  my $self = shift;

  # Routes
  my $r = $self->routes;
  $r->get('/')->to('main#default');
}

アプリケーションクラスでよく使用するメソッド

SampleappはMojoliciousを継承していて、MojoliciousはMojoを継承していますので、それらのメソッドを使用することができます。この中でよく使用するメソッドをいくつか紹介しておきます。

log - ロガーの取得

Mojoliciousにはログを設定レベルに応じて出力する機能があります。その機能は「Mojo::Log」というクラスで実装されています。

アプリケーションクラスはMojo::Logオブジェクトを持っており「log」メソッドで取得することができます。startupメソッドの中では$selfがアプリケーションを表すオブジェクトなのでここからlogを呼ぶことができます。

sub startup {
  my $self = shift;

  # ロガーの取得
  my $log = $self->log;
    
  # デバッグレベルでログに出力
  $log->debug('message');
}

home - ホームオブジェクトの取得

Mojoliciouにはアプリケーションのホームディレクトリを表現する「Mojo::Home」というクラスがあります。このオブジェクトを取得するには「home」メソッドを使用します。

sub startup {
  my $self = shift;

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

設定ファイルを読み込む

設定(コンフィグ)ファイルを読み込むにはMojolicious::Plugin::Configを利用します。以下はアプリケーションのホームディレクトリにあるmyapp.confを読み込むサンプルです。

# Mojolicious Lite
my $conf = plugin('Config', {file => $self->app->home->rel_file('myapp.conf')});

# Mojolicious
my $conf = $self->plugin(
  'Config',
  {file => $self->app->home->rel_file('myapp.conf')}
);

以下は設定ファイルのサンプルです。データベースの情報などを設定ファイルに書いておくことができます。

{
  db_dsn => "DBI:mysql:database=bookshop;",
  db_user => "ken",
  db_password => "FJ5klsd%&"
}

モードに応じた設定ファイルのカスタマイズ

Mojoliciousではモードに応じて設定ファイルの内容をカスタマイズすることができます。モードに応じた設定は

myapp.production.conf

のように

設定ファイル名.モード名.拡張子

という名前にしたファイルに記述します。

たとえば、データベースのパスワードを本番環境用のものにカスタマイズするには次のようにdb_passwordの値を上書きます。

# myapp.production.conf
{
  db_password => "change!!!!"
}

二つの設定ファイルを読み込む

ときには設定ファイルを分けて、二つの設定ファイルを読み込みたい場合があると思います。そんなときは、Configプラグインを単純に二回使えばよいだけです。ハッシュのキーが同じ場合は設定が上書かれます。

$app->plugin(Config => {file => $conf_file1});
$app->plugin(Config => {file => $conf_file2});

ログを世代管理する

Mojoliciousを本番環境でhypnotoadで運用した場合は、production.logというログがだんだんと蓄積されていきます。

ログを管理するにはCentOSであれば、logrotateを利用するのが簡単です。アプリケーションのあるディレクトリにディレクトリに、logrotateの設定ファイルを配置しましょう。今回はホームディレクトリの下にwebappディレクトリがあるとします。

cd webapp
mkdir logrotate
cd logrotate
vi logrotate.conf

以下のように設定ファイルを記述します。1週間に1回、ログファイルをコピーしてローテーションさせる設定にしています。

/home/ken/webapp/log/production.log {
  weekly
  copytruncate
  rotate 12
  missingok
}

後はローテーションを実際に実行するコマンドをcrontabに登録しましょう。

crontab -e

以下の内容を記述します。

0 0 * * * /usr/sbin/logrotate -s $HOME/webapp/logrotate/logrotate.status $HOME/webapp/logrotate/logrotate.conf

ブラウザのショートカットアイコン(ファビコン)を変更する

Mojoliciousではデフォルトで雲のマークのファビコンが表示されますが、変更するのは簡単です。

publicディレクトリ以下にfavicon.icoという名前で配置するだけです。

public
  - favicon.ico

古いファビコンはブラウザにキャッシュされるので確認するときは、ブラウザのキャッシュを削除する必要があるかと思います。

またファイル名を指定してファビコンを設置したい場合はHTMLのlinkタグでrelにshortcut iconを指定して以下のようにします。publicディレクトリ以下にexample.icoという名前でファビコンを設置しています。

use Mojolicious::Lite;

get '/' => 'index';

app->start;

__DATA__

@@ index.html.ep
<html>
  <head>
    <link rel="shortcut icon" href="<%= url_for '/example.ico' %>">
    <title>Favicon Example</title>
  </head>
  <body>
    Favicon Example
  </body>
</html>

Perl5.8.7でMojoliciousを使う方法

Cent OSのバージョン5はまだ広く利用されていて、新しいバージョンに移行していくのには、かなりの時間がかかりそうだと僕は思っている。Perlのバージョンは悲しいことに5.8.7。でもうれしいことにPerl5.8.7で実行できるようにMojoliciousをバックポートするプロジェクトがある。

これを利用すれば、ポータビリティの高いWebアプリケーションをMojoliciousを使って書くことができる。

ログを確認する

Mojoliciousを使って開発をしていると、ソースコードが間違っていたときなどに、どんなエラーが発生しているのかを確認したいときがあります。そんなときはログを確認してみましょう。

スクリプトと同一ディレクトリにlogディレクトリがあれば、そのディレクトリにログが出力され、そうでない場合は、標準エラー出力に内容が出力されます。

通常はlogディレクトリを作成しておくのが便利でしょう。

# Mojolicious::Liteの場合
myapp.pl
log/
# Mojoliciousの場合
script/myapp
log/

ログの名前

ログはlogディレクトリに出力されますが、ログ名には次のような規則があります。

モード名.log

たとえばmorboを使って、開発モードでアプリケーションを実行しているときはログ名はdevelopment.logになります。morboで実行したときのデフォルトのモードはdevelopmentだからです。

log/development.log

また本番環境でhypnotoadを使って実行しているときは、ログ名はproduction.logになります。hypnotoadで実行するときはモード名としてデフォルトでproductionが設定されるからです。

log/production.log

モードを変更するにはmodeメソッド(Mojoliciousクラス)を使用します。

# Mojolicious::Liteの例
app->mode('test');

# Mojoliciousの例
sub startup {
  my $self = shift;
  $self->mode('test');
}

Unix/Linuxでのログを確認する便利な方法

Unix/Linuxではtailコマンドを使うとログの確認が便利です。新しくログが出力されたときに、自動的にその内容を表示してくれます。

tail -f log/development.log

データをダンプする dumper

Webアプリケーションを作成しているとデータをダンプしてみたいことが良くあります。Mojoliciousでは単純にdieを行えば例外クラスのテンプレートが呼ばれてデータをダンプすることができます。

dumperを使って以下のようになります。

die dumper $data;

リモートのIPアドレスを取得する

リモートのIPアドレスを取得するにはMojo::Transactionのremote_addressメソッドを使用します。これはCGIの環境変数におけるリモートホスト(REMOTE_ADDR)に該当するものを取得します。

# リモートのIPアドレスを取得
$c->tx->remote_address;

コントローラーオブジェクトからMojo::Transactionオブジェクトをtxメソッドで取得、そこからremote_addressメソッドを呼び出し、リモートのIPアドレスを取得します。

ユーザーエージェント(HTTPヘッダ User-Agent)を取得する

アクセスしているユーザーエージェント(User-Agent)を取得するには、Mojo::Headerのuser_agentメソッドを使用します。

# ユーザーエージェントヘッダを取得
$c->req->headers->user_agent;

コントローラーオブジェクトからMojo::Requestオブジェクトをreqメソッドで取得、Mojo::Headerオブジェクトをheadersメソッドで取得、そこからuser_agentメソッドを呼び出します。

httpsからのセキュアな接続かどうかを調べる

接続が、httpsからのセキュアな接続かどうかを調べるにはMojo::Message::Requestクラスのis_secureメソッドを使用します。

my $secure = $req->is_secure;
Giblog