Moose:如何获取对象数组?特质?
Moose: How to get an array of objects? Traits?
我开始意识到这是给初学者的:
package Bad;
has 'arr' => ( is => 'rw', 'ArrayRef[Str]' );
package main;
my $bad = Bad->new(arr => [ "foo", "bar" ]);
print $bad->arr->[0], "\n";
输入特征。不过,我对 API 的特点不感兴趣。我误解了什么吗?我能以某种方式得到这个 API 吗? :
print $bad->arr->get(0), "\n";
详情
查看 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;
使用了这样声明的对象,例如:
my $option = $stuff->get_option(1);
我真的不喜欢我得到的一个数组属性,并且必须在我的 Stuff class 中手动命名 11 个方法 - 一个方法用于可以对 'options' 执行的每一个操作。肯定会出现命名不一致的情况,很臃肿
我如何(优雅地)得到一个 API 像:
my $option = $stuff->options->get(1);
Moose::Meta::Attribute::Native::Trait::Array 中的所有方法都以类型安全的方式实现了吗?
然后每个数组上的所有操作都以完全相同的方式命名...
(我实际上使用的是 Mouse,但 Mouse 的大部分内容与 Moose 相同)
我认为将 API 转换为该格式的最佳方法是为选项创建一个新对象,并将方法直接委托给它。类似于:
package Stuff;
use Moose;
use Stuff::Options;
has 'options' => (
'is' => "ro",
'isa' => "Stuff::Options",
'default' => sub { Stuff::Options->new },
);
no Moose;
1;
然后在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;
这将允许您示例中的代码工作 ($stuff->options->get(1)
)。
我开始意识到这是给初学者的:
package Bad;
has 'arr' => ( is => 'rw', 'ArrayRef[Str]' );
package main;
my $bad = Bad->new(arr => [ "foo", "bar" ]);
print $bad->arr->[0], "\n";
输入特征。不过,我对 API 的特点不感兴趣。我误解了什么吗?我能以某种方式得到这个 API 吗? :
print $bad->arr->get(0), "\n";
详情
查看 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;
使用了这样声明的对象,例如:
my $option = $stuff->get_option(1);
我真的不喜欢我得到的一个数组属性,并且必须在我的 Stuff class 中手动命名 11 个方法 - 一个方法用于可以对 'options' 执行的每一个操作。肯定会出现命名不一致的情况,很臃肿
我如何(优雅地)得到一个 API 像:
my $option = $stuff->options->get(1);
Moose::Meta::Attribute::Native::Trait::Array 中的所有方法都以类型安全的方式实现了吗?
然后每个数组上的所有操作都以完全相同的方式命名...
(我实际上使用的是 Mouse,但 Mouse 的大部分内容与 Moose 相同)
我认为将 API 转换为该格式的最佳方法是为选项创建一个新对象,并将方法直接委托给它。类似于:
package Stuff;
use Moose;
use Stuff::Options;
has 'options' => (
'is' => "ro",
'isa' => "Stuff::Options",
'default' => sub { Stuff::Options->new },
);
no Moose;
1;
然后在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;
这将允许您示例中的代码工作 ($stuff->options->get(1)
)。