穆斯:如何获得一系列物体?特点?

Pet*_*rch 5 perl moose

我开始意识到这适合初学者:

package Bad;

has 'arr' => ( is => 'rw', 'ArrayRef[Str]' );

package main;

my $bad = Bad->new(arr => [ "foo", "bar" ]);
print $bad->arr->[0], "\n";
Run Code Online (Sandbox Code Playgroud)

输入特征.不过,我对特质API感到不知所措.我误解了什么吗?我能以某种方式获得此API吗?:

print $bad->arr->get(0), "\n";
Run Code Online (Sandbox Code Playgroud)

细节

查看Moose :: Meta :: Attribute :: Native :: Trait :: Array中的规范特征示例

package Stuff;
use Moose;

has 'options' => (
    traits  => ['Array'],
    is      => 'ro',
    isa     => 'ArrayRef[Str]',
    default => sub { [] },
    handles => {
        all_options    => 'elements',
        add_option     => 'push',
        map_options    => 'map',
        filter_options => 'grep',
        find_option    => 'first',
        get_option     => 'get',
        join_options   => 'join',
        count_options  => 'count',
        has_options    => 'count',
        has_no_options => 'is_empty',
        sorted_options => 'sort',
    },
);

no Moose;
1;
Run Code Online (Sandbox Code Playgroud)

像这样声明的对象用于例如:

my $option = $stuff->get_option(1);
Run Code Online (Sandbox Code Playgroud)

我真的不喜欢我获得的一个数组属性,并且必须在我的Stuff类中手动命名11个方法 - 一个用于每个操作,可以对'选项'执行操作.不一致的命名必然会发生,而且很臃肿.

我如何(优雅地)获得如下API:

my $option = $stuff->options->get(1);
Run Code Online (Sandbox Code Playgroud)

Moose :: Meta :: Attribute :: Native :: Trait :: Array的所有方法都是以类型安全的方式实现的吗?

然后,每个数组上的所有操作都以完全相同的方式命名...

(我实际上使用鼠标,但大多数鼠标与Moose相同)

AKH*_*and 5

我认为将API转换为该格式的最佳方法是为选项创建一个新对象,并将方法直接委托给它.就像是:

package Stuff;
use Moose;
use Stuff::Options;

has 'options' => (
    'is'      => "ro",
    'isa'     => "Stuff::Options",
    'default' => sub { Stuff::Options->new },
);

no Moose;
1;
Run Code Online (Sandbox Code Playgroud)

然后在Stuff/Options.pm:

package Stuff::Options;
use Moose;

has '_options' => (
    'is'      => "ro",
    'isa'     => "ArrayRef[Str]",
    'traits'  => [ "Array" ],
    'default' => sub { [] },
    'handles' => [ qw(elements push map grep first get join count is_empty sort) ],
);

no Moose;
1;
Run Code Online (Sandbox Code Playgroud)

这将允许代码中的代码工作($stuff->options->get(1)).