2009-02-24 58 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')。