2009-02-24 7 views
8

Je commence actuellement avec Perl OOP en utilisant le paquet "Moose".Comment gérer les paramètres optionnels dans Moose?

Le compilateur se plaint qu'il "ne peut pas modifier l'appel de sous-routine non-lvalue à Parser.pm ligne 16."

Je ne comprends pas très bien pourquoi je ne peux pas simplement assigner un nouvel objet. Je suppose qu'il existe une meilleure façon de faire des paramètres optionnels avec Moose?

#!/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

Je ne vois aucune connexion aux paramètres facultatifs. Pouvez-vous développer? – ysth

Répondre

13

$self->mech est un appel de méthode; vous ne pouvez pas vraiment le traiter comme un champ dans un C struct. Si vous voulez le définir, vous devez lui passer le nouvel objet.

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

Alors que Perl a fourni la possibilité d'utiliser les attributs de la façon dont vous essayez de pour un bon nombre d'années (par ce qu'on appelle lvalue sous-marins), ce n'est pas quelque chose qui était dans la première OO Perl libère, et les à peu près appris à faire sans. D'autant plus que la mise en œuvre de la validation est un peu délicate (et inefficace).

Vous pouvez utiliser MooseX::Meta::Attribute::Lvalue, mais (selon le document) au prix de ne pas avoir de vérification de type sur certains attributs.

Je vous recommande de coller simplement au style $ self-> attribute ("value").

+0

N'utilisez pas ce module, il est cassé par conception. –

+0

@Dave Rolsky: de la manière que j'ai noté, ou d'une autre manière? – ysth

6

Probablement la façon Moose préféré de le faire est de mettre lazy_build sur l'attribut:

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 
    ); 
} 

Cela permettra à l'attribut « mech » pour obtenir peuplé la première fois qu'il est appelé, sauf indication contraire par la constructeur ou par l'accesseur (puisque c'est toujours 'rw').

+0

Merci d'avoir répondu à cette question et à votre explication! –

Questions connexes