0

次のコードでは、パラメーター化されたロール内の属性のトリガーを定義しようとしました。

#!/usr/bin/env perl

package WordSizeRoleParameterized;
use MooseX::Role::Parameterized;

# a parameterized role with a trigger for an attribute
# does not work
role {   
    has 'word' => ( is => 'rw', trigger => \&_trigger_word_size,);

    has 'word_size' => ( is => 'ro', writer => '_set_word_size', );

    method '_trigger_word_size' => sub {
        my $self = shift;
        my $size;

        if ( $self->word ) { $size = split //, $self->word; }
        else               { $size = 0; }

        print "WordsizeRoleParameterized::_trigger_word_size() called : size = $size \n";
        $self->_set_word_size($size);
    };
};

1;

package WordSizeRole;
use Moose::Role;

# a plain role with a trigger for an attribute
# works as expected 
    has 'word' => ( is => 'rw', trigger => \&_trigger_word_size,);

    has 'word_size' => ( is => 'ro', writer => '_set_word_size', );

    sub _trigger_word_size {
        my $self = shift;
        my $size;

        if ( $self->word ) { $size = split //, $self->word;}
        else               { $size = 0;}
        $self->_set_word_size($size);
    }

1;

package ClassWordSizeParameterized;
use Moose;
with 'WordSizeRoleParameterized';
1;

package ClassWordSize;
use Moose;
with 'WordSizeRole';
1;

#------------
package main;
#------------

use strict;
use warnings;

# no error
my $wordy = ClassWordSize->new({'word' => 'goodie'});
print "word : '", $wordy->word, "', size: ", $wordy->word_size, "\n";

# but using the paramaeterized role ...
my $wordy_parameterized = ClassWordSizeParameterized->new();

# will cause an error if calling $wordy_parameterized->word('Superdubadubaduuuh')); 
#
# Undefined subroutine &WordSizeRoleParameterized::_trigger_word_size called at accessor
# ClassWordSizeParameterized::word (defined at roleTrigger.pl line 8) line 7.
$wordy_parameterized->word('Superdubadubaduuuh');
print "word : '", $wordy_parameterized->word, "', size: ", $wordy_parameterized->word_size, "\n";

$ wordy_parameterized-> word('Superdubadubaduuuh')を呼び出すと、トリガールーチンが起動され、次のエラーが発生します。未定義のサブルーチン&WordSizeRoleParameterized :: _ trigger_word_size

興味深いことに、メソッドWordSizeRoleParameterized :: _ trigger_word_sizeが存在します($ wordy_parameterized-> _ trigger_word_size();を呼び出すことができます)が、属性のトリガールーチンとしては起動されません。MooseX :: Role :: Parameterizedのドキュメントには、それについて何も書かれていません。

MooseX :: Role :: Parameterizedの実装の詳細によって、許可されていないか、単純に不可能ですか?

4

1 に答える 1

1

多かれ少なかれ実装の詳細ですMooseX::Role::Parameterized。キーワードを使用すると、パッケージmethodにメソッドは作成されません。WordSizeRoleParameterized同様にhas、ブロックで使用する他のキーワードは、を使用role {}するパッケージには影響しませんMooseX::Role::Parameterized。このような宣言は、role {}ブロックがバックグラウンドで生成する匿名ロールにのみ影響し、その後、その匿名ロールを消費するクラス (または他のロール) に影響します。

ここでの問題は\&_trigger_word_size、間違ったパッケージにバインドされていることです (WordSizeRoleParameterized匿名ロールのパッケージにバインドする必要がある場合)。に変更\&_trigger_word_sizeするとsub { shift->_trigger_word_size(@_) }、通常のメソッド解決が使用されるため、適切なパッケージ ( ClassWordSizeParameterized) でメソッドが検出されます。

word : 'goodie', size: 6
WordsizeRoleParameterized::_trigger_word_size() called : size = 18 
word : 'Superdubadubaduuuh', size: 18

$wordy_parameterized->_trigger_word_sizeメソッドが ではなく、匿名ロールを介してクラスにコピーされているためですWordSizeRoleParameterized

于 2012-06-08T19:22:37.613 に答える