在参数化角色中定义属性触发器不起作用 - 不允许/不可能?

时间:2012-06-08 19:02:03

标签: perl moose

在下面的代码中,我尝试为a中的属性定义触发器 参数化角色。

#!/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的一些实现细节是不允许的还是不可能的?

1 个答案:

答案 0 :(得分: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

相关问题