CodeZine(コードジン)

特集ページ一覧

初めてのCatalyst入門(6)
Perlのオブジェクト指向とモデル

blessとMooseの違い、Catalystのモデルについて解説

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/01/26 14:00
目次

Mooseを使用した例

 次にMooseを使用してPersonBaseballPlayerを定義する例を見ていきましょう。Mooseではblessをそのまま使用する場合に比較して、プロパティやメソッドのオーバーライドなどが簡単に定義できるようになっています。

[リスト5]Moose版Personクラス
package moosified::Person;
# (1)Mooseを読み込む
use Moose;
# (2)プロパティの定義
has 'name' => (
  is  => 'rw',
  isa => 'Str',
  default => 'none',
);
has 'age' => (
  is  => 'ro',
  isa => 'Int',
  default => 0,
);
sub introduce {
  my $self = shift;
  print 'My name is ' , $self->name() , ', ' , $self->age() , " years old.\n";
}
# (3)Mooseの関数を名前空間から削除し、クラスを不変化する
no Moose;
__PACKAGE__->meta->make_immutable;

1;

 blessを使用した定義に比べると、newメソッドがない、プロパティ定義らしき部分に「has 'name' => (...)」と記述されている、などの違いが見て取れると思います。

 Mooseを使用するには(1)のように「use Moose」でMooseを読み込みます。このときにuse strictuse warningsも同時に設定されます。またMooseで定義されているhasなどの関数も併せて読み込まれます。Mooseでのプロパティ定義は(2)のようにhas関数を使用して行います。hasで使用可能な主要オプションには次のようなものがあります。

 その他のオプションについてはMoose#EXPORTED_FUNCTIONSの項目を参照ください。

hasで使用可能なオプション(一部)
名前 指定可能な値 説明
is roまたはrw プロパティへのアクセスが読み込み専用か読み書き可能かを設定する
isa データ型 プロパティへのデータ型を設定する
default スカラ値またはコード デフォルト値を設定する。スカラ値だけではなくデフォルト値を生成するコードも指定可能
required 0または1 newメソッドで必須の場合には1を、そうでない場合には0を設定する
trigger コードへの参照 プロパティへ値が設定された場合に、指定したコードが実行される
clearer クリア用メソッド名 プロパティ値をクリアするためのメソッド名を指定すると、Mooseにより自動的にその名前でメソッドが追加される
predicate 値が設定されているか判定するメソッド名 プロパティに値が設定されているかどうかを判定するためのメソッド名を指定すると、Mooseにより自動的にその名前でメソッドが追加される
coerce 0または1 1に設定した場合にはisaで指定した型以外の値が渡された場合に強制的な型変換を行う

 最後の部分(3)では、no Mooseを指定することでMoose関連の関数を名前空間から削除し、__PACKAGE__->meta->make_immutableでクラスを不変化させます。不変化させると、これ以降ではクラスへのプロパティの追加などはできなくなりますが、実行時にはクラスが高速に動作するようになります。

 次に、Mooseを使ってPersonから継承させたBaseballPlayerを見ていきましょう。こちらの場合にも、use Mooseで始まり、最後はno Moose__PACKAGE__->meta->make_immutableを呼び出しています。

[リスト6]Moose版BaseballPlayerクラス
package moosified::BaseballPlayer;
use Moose;
#(1)moosified::Personから継承させる
extends 'moosified::Person';

has 'team' => (
  is  => 'rw',
  isa => 'Str',
  default => 'none',
);
#(2)introduceをオーバーライドする
override 'introduce' => sub {
  my $self = shift;
  super();
  print "\tAnd I belong to " , $self->team() , ".\n";
};

# 省略

 Mooseで継承させるには、(1)のようにextends関数に継承元となるクラス名を指定します。メソッドをオーバーライドさせるには、(2)のようにoverrideメソッドを使用します。overrideで指定したメソッドからは、super()を使って継承元のメソッドを呼び出すことができますが、このときsuper()には引数を指定することができません(指定しても無視されます)。override指定したメソッドに引数が渡された場合には、それがそのまま継承元のメソッドに渡されます。

 overrideなどの、メソッドの振る舞いを変更することができる機能はメソッド修飾子と呼ばれます。メソッド修飾子には他にもbeforeafteraroundといったものが用意されています。fooメソッドに対してbeforeafteraroundを適用した例は次のようになります。

[リスト7]before、after、arroundの例
package Example;
use Moose;

sub foo {
  print "foo\n";
}
# (1)before
before 'foo' => sub { print "before foo\n"; };
# (2)after
after 'foo' => sub { print "after foo\n"; };
# (3)around
around 'foo' => sub {
  my $orig = shift;
  my $self = shift;
  print "before foo in around\n";
  # fooの呼び出し
  $self->$orig(@_);
  print "after foo in around\n";
};
# fooメソッドを呼び出す
Example->new->foo;

 ▼

実行結果
before foo
before foo in around
foo
after foo in around
after foo

(1)before

 beforeで指定したサブルーチンは、fooメソッドが呼び出される前に実行されます。一般的には、メソッドやプロパティの値チェックなどで使用されます。サブルーチンからの返値は無視されます。

(2)after

 afterで指定したサブルーチンは、fooメソッドが呼び出された後で実行されます。一般的には、ログを記録したりする場合などで使用されます。beforeと同様にサブルーチンからの返値は無視されます。

(3)around

 aroundでは、最初の引数に元のメソッド(この例だとfooメソッド)、2番目の引数にオブジェクト、それ以降では元のメソッドへの引数が渡されます。実行例からも分かるように、beforearoundの前、afteraroundの後に実行されます。

 aroundを使うと、引数の値によっては元のメソッドを呼び出さないこともできますし、返値を書き換えることもできるようになります。

 それでは、Moose版のPersonBaseballPlayerの動作を確認するスクリプトをmoosified_test.plという名前で定義してみます。

 内容はblessed_test.plとほとんど同じで、blessed::の部分をmoosified::に変更するだけでそのまま動作します。

 このスクリプトを実行し、出力される結果を確認しましょう。

[リスト8]moosified_test.plの実行
$ perl moosified_test.pl

 ▼

実行結果
Matsui
35
My name is Matsui, 35 years old.
My name is Suzuki, 36 years old.
        And I belong to Mariners.

 Mooseを使うとblessを使った場合に比べ、より簡潔な記述で、より多くのことを実現することができるようになりますが、その代償としてメモリ使用量の増加とコンパイル時の処理速度の低下がみられます。Moose自身にも最適化が加えられていますが、どうしても実行速度を向上させたい場合には、MouseClass::Accessor::Fastなどの選択肢もあります。

 特にMouseは、hasなどのクラス定義については、多くの部分でMooseとの互換性を保つように実装されています。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:Webアプリケーションフレームワーク「Catalyst」入門

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 花田 善仁(ハナダ ヨシヒト)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5