2009-02-24 65 views
8

我目前從Perl OOP開始使用「Moose」包。如何處理Moose中的可選參數?

編譯器抱怨說「無法修改Parser.pm第16行的非左值子程序調用」。

我不明白爲什麼我不能只分配一個新的對象。我想有一個更好或更有效的方式來做與穆斯可選參數?

#!/usr/bin/perl -w 

package Parser; 

use Moose; 

require URLSpan; 

require WWW::Mechanize; 

has 'urlspan' => (is => 'rw', isa => 'URLSpan', required => 1); 
has 'mech' => (is => 'rw', isa => 'WWW::Mechanize'); 

sub BUILD { 
    my $self = shift; 
    if(!$self->mech) { 
     warn("no Mech set for " . $self->urlspan->name); 
     $self->mech = WWW::Mechanize->new(agent => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.4', 
             stack_depth => 1 
             ); #line 16 
     } 

} 
+1

我看不到可選參數的任何連接。你可以擴展嗎? – ysth 2009-02-24 18:18:12

回答

13

$self->mech是一個方法調用;你不能像C結構中的字段那樣真正地對待它。如果你想設置它,你需要傳遞新的對象。

 $self->mech( 
      WWW::Mechanize->new(
       agent => 'xyz', 
       stack_depth => 1 
      ) 
     ); 
5

雖然Perl已經提供給使用屬性您嘗試了好多年(通過所謂的左值潛艇),它不是東西,是在第一OO Perl的方式釋放的能力,以及人幾乎學會了沒有它。特別是由於實施驗證有點棘手(並且效率低下)。

您可以使用MooseX::Meta::Attribute::Lvalue,但(根據文檔)的代價是沒有對某些屬性進行類型檢查。

我建議只要堅持$ self->屬性(「價值」)的風格。

+0

不要使用該模塊,它的設計會被破壞。 – 2009-02-25 04:17:46

+0

@Dave Rolsky:以我注意到的方式,還是以某種其他方式? – ysth 2009-02-25 16:04:21

6

也許這樣做的首選駝鹿方法是設置lazy_build的屬性:

has 'mech' => (is => 'rw', isa => 'WWW::Mechanize', lazy_build => 1); 
sub _build_mech { 
    warn("no Mech set for " . $self->urlspan->name); 
    WWW::Mechanize->new(
      agent => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.6)'. 
        ' Gecko/2009011913 Firefox/3.0.4', 
      stack_depth => 1 
    ); 
} 

這將允許屬性「機甲」,以獲取填充它第一次被調用時,除非另有設置構造函數或訪問者(因爲它仍然是'rw')。