我想设置一个属性,该属性是一个arrayrefs数组,其中nonarrayrefs强制转换为数组引用。例如
[0,[0,0,0],[1,2,3]]变为[[0],[0,0,0],[1,2,3]]
另外,我也希望能够通过强制将元素推送或设置到AoA。这是我的尝试:
{
package MyArray;
use namespace::autoclean;
use Moose::Util::TypeConstraints;
use Moose;
subtype 'My::ArrayRef' => as 'ArrayRef';
coerce 'My::ArrayRef'
=> from 'Num|Str'
=> via {[$_]};
has 'ents' => (
traits => ['Array'],
is => 'rw',
isa => 'ArrayRef[My::ArrayRef]',
default => sub { [] },
handles => {
push => 'push',
get => 'get',
set => 'set',
elements => 'elements',
count => 'count',
},
coerce => 1,
);
__PACKAGE__->meta->make_immutable;
}
use Modern::Perl;
my $a0 = MyArray->new( ents => [ 0, [ 0, 0, 0 ], [1,2,3] ] ) ;
use Data::Dumper;
print Dumper $a0;
$a0->set(0,'cat');
print Dumper $a0;
$a0->push(1.0);
print Dumper $a0;
答案 0 :(得分:4)
类型需要在强制之前不匹配,但在之后成功。
这就是诀窍(经过测试):
my $array_ref = Moose::Util::TypeConstraints::find_type_constraint('ArrayRef');
# Create an alias so we don't affect others with our coercion.
subtype 'My::Data::Structure'
=> as 'ArrayRef[ArrayRef[Str|Num]]';
coerce 'My::Data::Structure'
=> from 'ArrayRef[ArrayRef[Str|Num]|Str|Num]'
=> via { [ map $array_ref->check($_) ? $_ : [ $_ ], @$_ ] };