简体   繁体   English

Perl Moose 对象可以直接具有数组/哈希属性吗?

[英]can Perl Moose objects have directly an array/hash attribute?

Can be done something like this in Perl?可以在 Perl 中做这样的事情吗?

package Person;
use Moose;

has 'friends' => ( is => 'rw', isa => 'Array', default => () );

I see that perl compiler doesn't accept this particular syntax, but do I use wrong syntax, or it is not possible at all?我看到 perl 编译器不接受这种特定的语法,但是我使用了错误的语法,还是根本不可能? Do I have to use an array reference instead?我必须使用数组引用吗?

I'm pretty new to perl so the question is maybe dumb and I somehow feel the answer would be "no", but I haven't found any mention about it.我对 perl 很陌生,所以这个问题可能很愚蠢,我不知何故觉得答案是“不”,但我没有发现任何提及。

Thanks in advance提前致谢

"List" has quite a few definitions. “列表”有很多定义。 Presuming you mean an collection or ordered collection of Person objects, I'd use an array I'd pass to the accessor using a reference假设您的意思是 Person 对象的集合或有序集合,我将使用一个数组,我将使用引用传递给访问器

has friends => (
   is      => 'rw',
   isa     => 'ArrayRef[Person]',
   default => sub { [] },
);

push @{ $o->friends }, $person;

for (@{ $o->friends }) {
   ...
}

You can add useful methods using Moose::Meta::Attribute::Native::Trait::Array .您可以使用Moose::Meta::Attribute::Native::Trait::Array添加有用的方法。

has friends => (
   traits  => [qw( Array )],
   is      => 'rw',
   isa     => 'ArrayRef[Person]',
   default => sub { [] },
   handles => {
      push_friends => 'push',
   },
);

$o->push_friends($person);

for (@{ $o->friends }) {
   ...
}

It's not quite what you're asking, but look at array traits - http://search.cpan.org/dist/Moose/lib/Moose/Meta/Attribute/Native/Trait/Array.pm .这不是你要问的,但看看数组特征 - http://search.cpan.org/dist/Moose/lib/Moose/Meta/Attribute/Native/Trait/Array.pm Since all of an instance's values are stored in a hashref, you can not store anything other than scalar values, meaning you need to use references.由于实例的所有值都存储在 hashref 中,因此您不能存储标量值以外的任何内容,这意味着您需要使用引用。 This handles all of the boilerplate you need to work with the internal arrayref.这将处理您需要使用内部 arrayref 的所有样板。

package Person;
use Moose;

has 'friends' => ( is => 'ro', 
                   traits  => ['Array'],
                   isa => 'ArrayRef[Str]',
                   default => sub { [] },
                   handles => {
                                 all_friends    => 'elements',
                                 add_friend     => 'push',
                                 map_friends    => 'map',
                                 filter_friends => 'grep',
                                 find_friend    => 'first',
                                 get_friend     => 'get',
                                 join_friends   => 'join',
                                 count_friends  => 'count',
                                 has_friends    => 'count',
                                 has_no_friends => 'is_empty',
                                 sorted_friends => 'sort',
                             },

                 );

As a simple answer that at least makes the get/set easier, you can write your own accessor functions to wrap an array ref into an array.作为至少使 get/set 更容易的简单答案,您可以编写自己的访问器函数来将数组 ref 包装到数组中。 For example:例如:

package Person;
use Moo;

has 'friendsRef' => ( is => 'rw', default => sub { []; } );

## A 'set/get' wrapper for friendsRef
sub Person::friends {
  my ($self, @list) = @_;
  return @{$self->friendsRef} unless $#list>=0;
  return $self->friendsRef(\@list);
}

## Example bonus function for adding to list
sub Person::addFriends {
  my ($self, @list) = @_;
  return push(@{$self->friendsRef}, @list);
}

Example code usage could be:示例代码用法可能是:

my $p = Person->new();

$p->friends('Dave','Jerry');
print "Friends are: ",join(', ',$p->friends()),"\n";

$p->friends('Bob','Dave');
print "Friends are: ",join(', ',$p->friends()),"\n";

$p->addFriends('Joe','Cletus');
print "Friends are: ",join(', ',$p->friends()),"\n";

## Note that "$p->friends()" is not a scalar, it's a sub returning an array,
## so instead of "$#{$p->friends()}" you'd want "scalar($p->friends())"
print "Number of friends is ",scalar($p->friends()),"\n";

Output is:输出是:

Friends are: Dave, Jerry          
Friends are: Bob, Dave            
Friends are: Bob, Dave, Joe, Cletus                                 
Number of friends is 4            

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM