Moose-0.92 > Moose::Manual::Classes

題名

Moose::Manual::Classes - クラスにMooseを使わせたり、サブクラス化したりする

Mooseを使う

Mooseの使い方は非常に簡単、use Mooseするだけです。

  package Person;

  use Moose;

これでMooseを使ったクラスができました!

もっとも、その裏では本当はいろいろなことが起こっています。ひとつひとつ見ていきましょう。

Mooseをロードすると、extendshaswithといったシュガー関数が山ほどクラスにエクスポートされます。これらの関数はクラスを定義するときに使います。たとえば、アトリビュートを定義したい場合はこのようにします。

  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::cleannamespace::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.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.