題名¶
Moose::Manual::Classes - クラスにMooseを使わせたり、サブクラス化したりする
Mooseを使う¶
Mooseの使い方は非常に簡単、use Moose
するだけです。
package Person;
use Moose;
これでMooseを使ったクラスができました!
もっとも、その裏では本当はいろいろなことが起こっています。ひとつひとつ見ていきましょう。
Mooseをロードすると、extends
、has
、with
といったシュガー関数が山ほどクラスにエクスポートされます。これらの関数はクラスを定義するときに使います。たとえば、アトリビュートを定義したい場合はこのようにします。
package Person;
use Moose;
has 'ssn' => ( is => 'rw' );
アトリビュートについてはMoose::Manual::Attributesのドキュメントをご覧ください。
また、Mooseをロードしたクラスではstrict
プラグマとwarnings
プラグマも有効になります。
Mooseをロードすると、そのクラスはMoose::Objectのサブクラスになります。Moose::Objectクラスにはデフォルトのコンストラクタやデストラクタのほか、オブジェクトを生成するヘルパーメソッドがあります。詳しくはMoose::Manual::Constructionのドキュメントをご覧ください。
また、Mooseは便利に使えるように、そのクラスのために新しい型も生成します。型についてはMoose::Manual::Typesのドキュメントをご覧ください。
さらに、そのクラスのMoose::Meta::Classオブジェクトも生成します。このメタクラスオブジェクトは、Person->meta
のようにクラスのmeta
メソッドを呼ぶと利用できます。
このメタクラスオブジェクトは、イントロスペクション用のAPIを提供します。Mooseも裏ではこのAPIを使ってアトリビュートを追加したり親クラスを定義したりしています。実は、Mooseのシュガー関数はどれも、実際にしているのはこのメタクラスオブジェクト(や、ほかのメタAPIオブジェクト)のメソッドを呼ぶことなのです。
サブクラス化¶
Mooseは親クラスを宣言するためにextends
という簡単なシュガー関数を提供しています。
package User;
use Moose;
extends 'Person';
has 'username' => ( is => 'rw' );
なお、親クラスはextends
を呼ぶたびに「リセット」されます。多重継承したい場合は、extends 'Foo', 'Bar'
のようにすべての親クラスを一度に指定する必要があります。
Mooseを使っていない親クラスをMooseを使って継承することもできますが、その場合、親クラスのコンストラクタを継承することになりますので(親クラスのコンストラクタもnew
という名前であれば、ですが)、アトリビュートの初期化は自分で(親クラスのコンストラクタか、サブクラスの中で)しなければなりませんし、Mooseの魔法もかなり使えなくなります。
no Moose¶
Mooseのシュガー関数はクラスの名前空間から削除することもできます。この機能を使うととにかくクラスが「きれい」になるのでおすすめです。この機能は、モジュールファイルの末尾にno Moose
を追加するだけで使えます。
package Person;
use Moose;
has 'ssn' => ( is => 'rw' );
no Moose;
こうするとMooseのシュガー関数がクラスの名前空間から消えるので、Person->can('has')
が真を返さなくなります。
Mooseを含め、それ以外のキーワードのエクスポート除去も行うさらに一般的な手法としてはnamespace::cleanやnamespace::autocleanがあります。
高速化する¶
Mooseには「不変化」という機能があります。この機能を使うと、実行時にクラスを大幅に高速化できます。ただし、この機能を使うと、クラスをはじめてロードするときにはコストがかかります。また、クラスを不変化すると、その先クラスを変更してアトリビュートやメソッド、ロールなどを追加することはできなくなります。
ただし、そのおかげでMooseはそのクラス専用のコードを生成することができるようになります。とりわけ「インライン」コンストラクタを生成するので、オブジェクトの生成が非常に速くなります。
クラスを不変化するには、単にそのクラスのメタクラスオブジェクトのmake_immutable
を呼んでください。
__PACKAGE__->meta->make_immutable;
不変化とnew()
¶
クラスのnew()
をオーバーライドしてしまうと、不変化用のコードがクラスに最適化したコンストラクタを用意できなくなってしまうので、BUILD()
メソッドを使うようにしてください。BUILD()
メソッドはインライン展開されたコンストラクタからも呼ばれます。
または、どうしても別のnew()
を用意する必要がある場合は、自前の不変化メソッドを用意することもできます。そのためにはMooseのメタクラスを拡張する必要がありますが、それについてはこのマニュアルでは取り扱いません。
作者¶
Dave Rolsky <autarch@urth.org>
コピーライト & ライセンス¶
Copyright 2008-2009 by Infinity Interactive, Inc.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.