Search code examples
perlmoose

Moose & isa ArrayRef


I am trying to use Moose with Moose::Meta::Attribute::Native::Trait::Array but it looks like ArrayRef helper doesn't work for me. Bellow is my code which returns

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

I use Moose 2.0007 and Perl v5.10.1. Moose::Autobox is installed. I would appreciate any suggestion.

#!/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;


Solution

  • handles add method to class itself, not to the attribute. Another problem is that splits attribute is still arrayref, so you need dereference in seconds foreach. Corrected code is as follows:

    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;
    }