2012-12-05 92 views
1

我有一組方法,我希望調用方能夠覆蓋一個值,或者它默認爲實例變量。設置MooseX :: Method :: Signatures默認爲一個實例變量

所以我一直試圖做的是:

method foo(Str :$blah = $self->blah) { 
    #doStuff 
} 

所以我最終做這個到處

method foo(Str :$blah?) { 
    $blah = $self->blah unless defined $blah; 
    #doStuff 
} 

不可怕,其拋出一個解析錯誤,但似乎愚蠢時MooseX ::方法::簽名支持默認的概念,並修復了我的其他標準'start of method'行。

當我試圖做這樣的事情時,我無法找到遇到同樣問題的網絡上的其他人,所以我以錯誤的方式接近問題。看起來好像我可能試圖將一個功能程序插入到oo佈局中,而不是實際的oo,因爲這些方法是更多的輔助函數,用於在外部調用而不是在對象上運行的方法。所以只要檢查我是不是正確地定義它,或者我所做的是「啞巴」還是僅僅不受Parse :: Method :: Signatures支持。

回答

1

AFAIK Signatures模塊將自己綁定到Perl分析器中,並注入一些代碼來處理原型。這很有意義,這是有效的。

也就是說,使用非常量值作爲默認值可能會有問題。在某些情況下,調用某些代碼預先填充值可能會造成嚴重破壞。具體而言,只有在沒有給出參數值時才應該調用預填充該值的代碼,還是應該始終調用它?我們應該如何處理副作用? caller應該是什麼?如果我有一個全球性的$self對象,不應該接受方法調用,因爲範圍規則明確規定了這一點? (由於our $x=5; my $x=$x;是有效的,但只是my $x=$x不是)。更妙的是,如果默認值的總體方法調用會調用相同的方法,但又沒有可選參數的值,會發生什麼?

您可以隨時退回到舊學校可選參數:

sub foo { 
    my ($self, $blah) = @_; 
    # something like my ($self, $blah) = (@_, $self->blah); wouldn't work, of course. 
    $blah //= $self->blah; # nicer than old `unless defined` 
    ...; 
} 

,或者在這種情況下:

method foo (:$blah?) { 
    $blah //= $self->blah 
} 

我發現這個使用定義,或運營商挺過癮的。

+0

我看到你要去哪裏與非常量值的東西。在我的腦海中,我期待着這個調用就像'除非定義'或'// ='代碼一樣。這是基於可能完全沒有根據的假設,方法簽名被解析爲它們表示和注入的子集,並且它將爲實際方法調用留下$ self。可能是時間來探討資料來源,看看它實際上做了什麼。感謝您的定義或提示,以前沒有見過。 – Matt

相關問題