クラスの作成は非常に簡単です。
package MyClass; use Moose;
すべて、空のクラスが作成されます。 任意の数の属性、メソッド、スーパークラス、メソッド修飾子、コンストラクター(1pc)、デストラクタ(1pc)、およびこのクラスに関するすべてのメタ情報を含むメタクラス(1pc)を持つことができます。
これらのコンポーネントの詳細:
クラス
各クラスは、Moose :: Objectのサブクラスです。 デフォルトでは、メタクラスおよびスーパークラスに固有の他のオブジェクトの形で、あらゆる種類の有用なオブジェクトの束を作成し、作成後にアクセスできます。
サブクラス
extendsキーワードを使用して継承が発生する
package User; use Moose; extends 'Person'; has 'username' => ( is => 'rw' );
多重継承、コンマで区切られたクラスを指定します:extends 'Foo'、 'Bar';
属性
属性には名前が必要であり、異なる数のプロパティを持つことができます:読み取り/書き込みフラグ、タイプ、アクセサメソッド、委任、デフォルト値など。
デフォルトでは、Mooseはクラスインスタンスに属性をハッシュとして保存します。 それらへのアクセスは、アクセサーを介して取得できます。
has-属性を宣言します
has 'first_name' => ( is => 'rw' );
isオプションの値は、[ro | rw | bare]読み取り専用、読み取り/書き込み、またはベア-この属性へのアクセサーなしです。
ゲッターとセッターは次のように設定できます。
has 'weight' => ( is => 'rw', reader => 'get_weight', writer => 'set_weight', );
述語 -属性が「undef」または別のfalse値の場合、trueを返します。
clearer-属性をリセットします
clearer-属性をリセットします
has 'ssn' => ( is => 'rw', clearer => 'clear_ssn', predicate => 'has_ssn', );
$person->has_ssn; # false $person->ssn(undef); $person->ssn; # returns undef $person->has_ssn; # true $person->clear_ssn; $person->ssn; # returns undef $person->has_ssn; # false $person->ssn('123-45-6789'); $person->ssn; # returns '123-45-6789' $person->has_ssn; # true
属性をインストールする必要性
プロパティを使用して設定できます:required => 1
デフォルトでは、すべての属性はオプションです。
属性はデフォルトで2つの方法で設定できます。
has 'size' => ( is => 'ro', default => 'medium', predicate => 'has_size', );
コンストラクターで設定されていない場合:
my $person = Person->new(); $person->size; # medium $person->has_size; # true
そして、メソッドへのリンクを設定できます:
has 'size' => ( is => 'ro', default => sub { ( 'small', 'medium', 'large' )[ int( rand 3 ) ] }, predicate => 'has_size', );
代替方法:
has 'size' => ( is => 'ro', builder => '_build_size', predicate => 'has_size', ); sub _build_size { return ( 'small', 'medium', 'large' )[ int( rand 3 ) ]; }
ビルダーはdefaultの代わりに使用することをお勧めします 。
最終ターンに属性のインストールを延期します
これは、プロパティを設定することで実現できます:lazy => 1
属性の初期値が他の要因に依存する場合に特に必要です。
このプロパティを使用するもう1つの利点は、必要な場合にのみ属性が計算され、必要でない場合はCPU時間を節約できることです。
属性タイプ
真珠の構造と同じタイプにすることができます:isa => 'Str'
またはオブジェクトにすることができます:does => 'MyApp :: Object'
複数の属性を設定する
has [ 'x', 'y' ] => ( is => 'ro', isa => 'Int' );
または:
for my $name ( qw( xy ) ) { my $builder = '_build_' . $name; has $name => ( is => 'ro', isa => 'Int', builder => $builder ); }
方法
クラスで宣言された関数はすべてクラスメソッドです。
メソッド修飾子
メソッド呼び出しの前(または「前、後、周囲、拡張」)に呼び出されます:
before 'atribute' => sub { my $self = shift; my $a = shift; print $a; };
役割
このクラスが実装する動作または状態。 他のオブジェクト指向言語のインターフェースの類似物。
use Moose :: Roleを使用して作成。
package Eq; use Moose::Role; requires 'equal_to'; sub not_equal_to { my ( $self, $other ) = @_; not $self->equal_to($other); }
ロールはクラスのように見えますが、クラスではありませんが、ロールをインスタンス化することはできません。 「requires」という言葉は 、このロールを使用するクラスはすべて「equal_to」メソッドを実装する必要があることを示しています。
package Comparable; use Moose; with 'Eq'; sub equal_to { my ( $self, $other ) = @_; $self->compare($other) == 0; } sub compare { my ( $self, $other ) = @_; $self->amount <=> $other->amount; }
コンストラクター/デストラクター
明示的に再定義する必要はありませんが、そのような必要が生じた場合は、コンストラクターとデストラクタにそれぞれBUILD()とDEMOLISH()を使用できます。
メタクラス
メタクラスはクラスを記述します。 Mooseでは、各クラスは「meta()」を提供し、Moose :: Meta :: Classオブジェクトを返します。 彼はこのクラスが何であるかについて話します。
my $meta = User->meta(); for my $attribute ( $meta->get_all_attributes ) { print $attribute->name(), "\n"; if ( $attribute->has_type_constraint ) { print " type: ", $attribute->type_constraint->name, "\n"; } } for my $method ( $meta->get_all_methods ) { print $method->name, "\n"; }
ごみの清掃
クラスの先頭に設定されている場合に発生します:use namespace :: autoclean;
またはクラスの終わりに:Mooseなし;
クラス加速
作業中にクラスが変更されない場合、その作業は次のように加速できます。
__PACKAGE__->meta->make_immutable;
それだけです、この知識はPerlでOOP構造をうまく作成するのに十分なはずですが、より深く理解するために、もちろんドキュメントを掘り下げて...はい、モジュールのソースコードでそうです(まあ、これは特別な場合です。場合、好奇心は誰も傷つけません)。