2012-06-08 17 views
0

在下面的代碼中,我試圖爲 參數化角色中的屬性定義觸發器。在參數化角色中定義attibute觸發器不起作用 - 不允許/不可能?

#!/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->字( 'Superdubadubaduuuh'),這應該火在錯誤觸發 例行結果: 未定義的子程序& WordSizeRoleParameterized :: _ trigger_word_size稱爲

Interstingly方法WordSizeRoleParameterized :: _trigger_word_size存在(您可以調用$ wordy_parameterized - > _ trigger_word_size();),但不會觸發該屬性的觸發器例程。 MooseX :: Role :: Parameterized的文檔沒有提及它。

MooseX :: Role :: Parameterized的某些實現細節是不允許的或者簡單的不可能的嗎?

回答

1

這或多或少是MooseX::Role::Parameterized的實現細節。當您使用method關鍵字時,它不會在WordSizeRoleParameterized包中創建方法。同樣,hasrole {}塊中使用的其他關鍵字不會影響使用MooseX::Role::Parameterized的軟件包。這些聲明僅影響後臺在後臺生成的匿名角色,然後影響使用該匿名角色的類(或其他角色)。

這裏的問題是,\&_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方式。

+0

非常感謝這個澄清的答案。大。在文檔中提及這些東西是否值得? – katastrophos

+0

它還沒有在文檔中,因爲你是我見過的第一個嘗試在MXRP中使用'\&function'的人。 :) – sartak

+0

我應該問Shawn M. Moore把它放到文檔中:-)))。我經常使用MXRP,並且總是有一種我不明白的魔法黑盒的感覺。文檔中的一點信息對像我這樣的人會有幫助。 – katastrophos