2011-05-27 75 views
3

我正在尝试使用Moose :: Meta :: Attribute :: Native :: Trait :: Array,但它看起来像ArrayRef helper不适用于我。贝娄是我的代码返回Moose&isa ArrayRef

Can't call method "add_item" on unblessed reference at bug.pl line 42.

我用驼鹿2.0007和Perl v5.10.1。 Moose :: Autobox已安装。 我会很感激任何建议。

#!/usr/bin/perl 

use strict; 

package CycleSplit; 
use Moose; 
has 'name'=>(isa=>'Str', is=>'rw'); 
has 'start'=>(isa=>'Num', is=>'rw'); 
has 'length'=>(isa=>'Num', is=>'rw'); 
1; 

package Cycle; 
use Moose; 
my @empty=(); 
has 'name' => (isa => 'Str', is => 'rw'); 
has 'splits' => (
    traits => ['Array'], 
    isa=>'ArrayRef[CycleSplit]', 
    is => 'rw', 
    default=>sub { [] }, 
    handles=>{ 
     add_item=>'push', 
    }, 
); 


no Moose; 
1; 

package Main; 

sub Main { 
    my $cyc=Cycle->new(); 
    $cyc->name("Days of week"); 

    for my $i (1..7) { 
     my $spl=CycleSplit->new(); 
     $spl->name("Day $i"); 
     $spl->start($i/7-(1/7)); 
     $spl->length(1/7); 
     $cyc->splits->add_item($spl); 
    } 

    my $text=''; 
    foreach my $spl ($cyc->splits) { 
     $text.=$spl->name." "; 
    } 

    print $text; 
} 

Main; 

+2

不是驼鹿专家,但尝试:$ cyc-> add_item($ spl); – snoofkin 2011-05-27 10:45:03

回答

11

handles将方法添加到类本身而不是属性。另一个问题是splits属性仍然是arrayref,因此您需要在几秒钟内解除引用foreach。更正后的代码如下:

sub Main { 
    my $cyc=Cycle->new(); 
    $cyc->name("Days of week"); 

    for my $i (1..7) { 
     my $spl=CycleSplit->new(); 
     $spl->name("Day $i"); 
     $spl->start($i/7-(1/7)); 
     $spl->length(1/7); 
     $cyc->add_item($spl);    # removed splits 
    } 

    my $text=''; 
    foreach my $spl (@{ $cyc->splits }) { # added array dereference 
     $text.=$spl->name." "; 
    } 

    print $text; 
} 
+5

请注意,您可以说'handles => {...,items =>'elements'}'并通过'items'直接获取列表而不需要解引用。我更喜欢这个变体,因为它不允许人们通过验证偷偷地看到数据。 – phaylon 2011-05-27 13:19:59

+1

@phaylon:同意;我从不使用'is =>'选项来处理本机特征属性,因此唯一的访问权限是通过委托方法。 – Ether 2011-05-27 19:07:25

+0

@其他 - 感谢您的提示。我总是使用委托方法,但忽略'is'没有出现在我身上。 – bvr 2011-05-28 05:22:47