Как мне обрабатывать необязательные параметры в Moose? - PullRequest
8 голосов
/ 24 февраля 2009

Я сейчас начинаю с Perl OOP, используя пакет "Moose".

Компилятор жалуется, что он "не может изменить вызов подпрограммы, не имеющий значения, в строке 16 Parser.pm".

Я не совсем понимаю, почему я не могу просто назначить новый объект. Я думаю, есть лучший или более правильный способ сделать необязательные параметры с 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
        }

}

Ответы [ 3 ]

13 голосов
/ 24 февраля 2009

$self->mech - это вызов метода; вы не можете действительно рассматривать это как поле в C-структуре. Если вы хотите установить его, вам нужно передать ему новый объект.

        $self->mech( 
            WWW::Mechanize->new(
                agent => 'xyz',
                stack_depth => 1
            )
        );
6 голосов
/ 03 марта 2009

Вероятно, предпочтительным способом Moose является установка 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
     );
}

Это позволит заполнить атрибут 'mech' при первом его вызове, если конструктор или метод доступа не установят иное (поскольку он по-прежнему равен 'rw').

5 голосов
/ 24 февраля 2009

Хотя Perl предоставляет возможность использовать атрибуты так, как вы пытаетесь в течение многих лет (через так называемые подпрограммы lvalue), это не то, что было в первых OO-версиях Perl, и люди в значительной степени научились обойтись без этого. Тем более что реализация валидации немного сложна (и неэффективна).

Вы можете использовать MooseX :: Meta :: Attribute :: Lvalue , но (согласно документу) за счет отсутствия проверки типов для некоторых атрибутов.

Я бы порекомендовал просто придерживаться стиля $ self-> attribute ("value").

...