2011-10-21 13 views
1

私はPerl/Mooseで継承のハングアップを始めましたが、私はいくつかの荒い斑点に遭遇し始めています。例えばなぜchildClassはparentClass関数とそれ自身の関数を呼び出すのですか?

は、継承されたオブジェクトのビルド順序は意味を成しているようだが、私の基本クラスの呼び出しはだけでなく、彼らのBUILDを呼ぶすべてのサブクラスを構築する場合、継承は、私が

をexpect--どのように動作するようには思えませんbaseClass 'BUILDですが、これはmoosey BUILD関数に限定されません。私は、基本クラスで関数init()を定義し、基底クラスのBUILDをitfrom呼び出す場合

は、サブクラスのinit()は簡潔にするため

と仮定()

O_O代わりに基底クラスのinitの呼び出されます酒、我々は以下のオブジェクト構造があること:

BaseClass 
    ::BUILD --> call init() 
    ::init --> do BaseStuff 

ChildClass extends BaseClass 
    ::BUILD --> call init() 
    ::init --> do ChildStuff 

を今すぐchildClass

my $child = ChildClass->new(); 
01をインスタンス化

新しいから結果の呼び出し順序は、()私のデバッグ出力

BaseClass->BUILD() 
BaseClass->init() <--- this calls ChildClass::init 
ChildClass->BUILD() 
ChildClass->init() <--- this calls ChildClass::init too! 

に基づいて私にはこのようになります私は彼らの両方のコールBUILDラムースを取得します。ファイン。私は、baseClassがなぜこのような場合にbaseClass :: initと呼ばれているのか、あるいはなぜchildClassが独自のchildClass :: BUILDを呼び出さないのかを誤解していると思います。

これらの機能を「オーバーライド」オーバーライド機能修飾子で特に「オーバーライド」する必要がありますか?

もし私がBUILDARGSを混ぜ合わせてしまえば、それは誰が引数をne​​w()に渡すのかということと、baseClassにそれに関連するロールがあるのですか?この場合、$クラスです

BaseClass (has role CanSee and has seesWith() attribute) 
BaseClass (has role NameTag and has name() attribute) 
ChildClass (has role FavoriteColor and has color() attribute) 

my $child = ChildClass->new(name => 'Jane', seesWith => 'eyes', color => 'red'); 

その後、

ChildClass 
     ::BUILDARGS --> 
      ($orig,$class,$args) = @_; 
      return $class->$orig(@_); 

?私は仮定してい

答えて

3

あなたは

sub BUILD { 
    my $self = shift; 
    ... 
    $self->init(); 
    ... 
} 

ムースお菓子のようなビットが異なっているBUILD各クラスのBUILD機能を持っている...笑私はBUILDARGSをオーバーライドする必要が私に教えてはいけないのPerl通常はメソッド呼び出しを処理します。 BUILDメソッドでinitを呼び出すと、Perlは通常のメソッド解決を使用し、親のinitメソッドをマスクするので、その子のinitメソッドを見つけます。子のメソッドは、$self->SUPER::init()、ムースの「オーバーライド」修飾子、そしてsuper()を親に呼び出すと、SUPER::を使用するように変更されました。

親クラスのBUILDメソッドでinitを呼び出す場合は、 'before'、 'after'、 'around'、または 'override'のような標準的なMooseメソッド修飾子を使用して、子クラスのinitがいつ親のinitに対する相対値と呼ばれます。

あなたは、そのクラスのビルドが実行されたときには、特に標準的な方法のルックアップをスキップし、指定されたクラスのメソッドを使用するようにPerlを依頼することができますと呼ばれる各クラスのinitたい一方場合:

package ParentClass; 

sub BUILD { 
    my $self = shift; 
    ... 
    $self->ParentClass::init(); 
    ... 
} 

package ChildClass; 

sub BUILD { 
    my $self = shift; 
    ... 
    $self->ChildClass::init(); 
    ... 
} 
関連する問題