8

現在、「Moose」パッケージを使用して Perl OOP から始めています。

コンパイラは、「Parser.pm の 16 行目で非左辺値サブルーチン呼び出しを変更できません」と文句を言います。

新しいオブジェクトを割り当てることができない理由がよくわかりません。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
        }

}
4

3 に答える 3

13

$self->mechメソッド呼び出しです。C 構造体のフィールドのように扱うことはできません。設定したい場合は、新しいオブジェクトを渡す必要があります。

        $self->mech( 
            WWW::Mechanize->new(
                agent => 'xyz',
                stack_depth => 1
            )
        );
于 2009-02-24T17:09:00.440 に答える
6

おそらく、これを行うための好ましい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'であるため)。

于 2009-03-03T15:56:38.887 に答える
5

Perl は、長い間 (左辺値サブルーチンと呼ばれるものを介して) あなたがしようとしている方法で属性を使用する機能を提供してきましたが、それは最初の OO Perl リリースにはなかったものであり、人々はそれなしで行うことをほとんど学びました。 . 特に検証の実装は少しトリッキーです (そして非効率的です)。

MooseX::Meta::Attribute::Lvalueを使用できますが、(ドキュメントによると)一部の属性の型チェックがないという犠牲が伴います。

$self->attribute( "value" ) スタイルに固執することをお勧めします。

于 2009-02-24T18:28:08.863 に答える