Moose:PerlのOOP

MooseはPerl 5の拡張機能であり、OOPを簡単に実装できます。



クラスの作成は非常に簡単です。

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構造をうまく作成するのに十分なはずですが、より深く理解するために、もちろんドキュメントを掘り下げて...はい、モジュールのソースコードでそうです(まあ、これは特別な場合です。場合、好奇心は誰も傷つけません)。



All Articles