2009-02-24 9 views
8

Ich beginne derzeit mit Perl OOP mit dem "Moose" -Paket.Wie gehe ich mit optionalen Parametern in Moose um?

Der Compiler beschwert sich, dass es "Nicht-lvalue Unterroutinenaufruf bei Parser.pm Zeile 16 nicht ändern kann".

Ich verstehe nicht ganz, warum ich nicht einfach ein neues Objekt zuweisen kann. Ich denke, es gibt einen besseren oder mehr gültigen Weg, optionale Parameter mit Moose zu machen?

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

Ich sehe keine Verbindung zu optionalen Parametern. Kannst du das weiter ausführen? – ysth

Antwort

13

$self->mech ist ein Methodenaufruf; Sie können es nicht wirklich wie ein Feld in einer C-Struktur behandeln. Wenn Sie es einrichten möchten, müssen Sie das neue Objekt an es übergeben.

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

Während Perl die Fähigkeit zur Verfügung gestellt hat Attribute so, wie Sie für ein gutes viele Jahre versuchen zu (über was lvalue subs genannt werden), ist es nicht etwas, das in dem ersten OO Perl war frei, und die Menschen ziemlich viel gelernt, ohne es zu tun. Zumal die Implementierung der Validierung ein wenig schwierig (und ineffizient) ist.

Sie könnten MooseX::Meta::Attribute::Lvalue, aber (nach dem Dokument) auf Kosten der Typüberprüfung auf einige Attribute verwenden.

Ich würde empfehlen, nur an den $ self> -Attribut ("Wert") Stil zu kleben.

+0

Verwenden Sie dieses Modul nicht, es ist durch das Design beschädigt. –

+0

@Dave Rolsky: in der Art, wie ich es notiert habe, oder auf andere Weise? – ysth

6

wahrscheinlich der bevorzugten Moos Weg, dies zu tun, ist auf dem Attribut gesetzt 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 
    ); 
} 

Dies wird dem Attribut ‚mech‘ ermöglicht das erste Mal zu bekommen bevölkerte sie genannt wird, sofern nicht anders durch die Menge Konstruktor oder vom Accessor (da es immer noch 'rw' ist).

+0

Danke, dass du auf diese Frage und deine Erklärung zurückkommst! –