如何设置 AoArrayrefs 属性并从标量强制转换为 arrayref?

发布于 2024-11-26 15:25:54 字数 1109 浏览 1 评论 0原文

我想设置一个属性,它是一个 arrayrefs 数组,并将非 arrayrefs 强制转换为数组引用。例如。

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

I would like to set up an attribute that is an array of arrayrefs with coercion of nonarrayrefs to array refs. eg.

[ 0, [ 0, 0, 0 ], [1,2,3] ] into [ [0], [ 0, 0, 0 ], [1,2,3] ]

also, I'd like to be able to push or set elements to the AoA with coercion as well. Here is my attempt:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如歌彻婉言 2024-12-03 15:25:54

该类型需要在强制转换之前匹配失败,但在强制转换之后成功。

这可以解决问题(已测试):

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($_) ? $_ : [ $_ ], @$_ ] };

The type needs to fail to match before the coercion, but succeed after.

This does the trick (tested):

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($_) ? $_ : [ $_ ], @$_ ] };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文