2011-10-21 21 views
1

我開始在Perl/Moose中獲得繼承權,但我開始遇到一些粗糙的問題。爲什麼childClass會調用它的parentClass函數以及它們自己的函數?

例如,繼承的對象的構建順序似乎是有道理的,但繼承似乎不工作,我如何expect--

如果我的基類的呼叫建立所有子類將調用其BUILD還有baseClass'BUILD,但這不僅限於moosey BUILD函數。

如果我定義的基類的函數的init(),並調用itfrom的基類BUILD,子類的init()被調用,而不是基類的init()

O_O

承擔簡潔起見,我們已經跟隨對象結構:

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

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

現在實例化childClass

my $child = ChildClass->new(); 

來自新產生的調用順序()看起來像這樣對我根據我的調試輸出

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

我得到他們兩個呼叫建立LA駝鹿。精細。我想我誤解了爲什麼baseClass在這種情況下不會調用它自己的baseClass :: init,或者爲什麼childClass不僅僅調用它自己的childClass :: BUILD。

我是否需要使用Moose「override」功能修飾符專門「覆蓋」這些功能?

然後,如果我把BUILDARGS放在混合中,它會變得更有趣,因爲問題是誰將參數傳遞給new()以及如果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(@_); 

這是在這種情況下,$類?

不要告訴我,我要重寫BUILDARGS ...笑

回答

3

我假設你在每類中的BUILD功能有點像

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

駝鹿對待BUILD不同的是Perl通常對待方法調用。當你在你的BUILD方法中調用init時,Perl將使用它的普通方法解析並找到子方法的init方法,因爲它掩蓋了父方法的init方法。然後,孩子的方法可以撥打$self->SUPER::init(),父母的'覆蓋'修飾符和super()只是修改方式使用SUPER::

如果你只在你的父類的BUILD方法中調用init,你可以使用任何標準的Moose方法修飾符,如'before','after','around'或'override'來控制子類的init是什麼時候稱爲相對於父級的init。

如果在另一方面,你要在這個類的構建運行,你可以明確要求Perl來跳過標準的方法查找並使用指定的類的方法被調用每個類的init:

package ParentClass; 

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

package ChildClass; 

sub BUILD { 
    my $self = shift; 
    ... 
    $self->ChildClass::init(); 
    ... 
} 
相關問題