Perl 用于多维数据结构的驼鹿特征
使用Attribute::Native::Trait处理程序可以轻松地将内部变量从对变量的调用分解为对对象的调用。但是,如何处理多个数据结构?我想不出任何方法来处理下面这样的事情,而不使存储成为My::stash::Attribute对象的arrayref,这反过来又包含My::stash::Subattribute对象的arrayref,其中包含一个arrayref My::stash::Instance对象。这包括在我整理数据时,在堆栈的每一层都进行大量的咀嚼和强制数据 是的,我可以将项目存储为平面数组,然后在每次读取时对其进行grep,但是在频繁读取且大多数调用都是读取的情况下,对大量数组项目进行grep需要大量处理每次读取,而不仅仅是以所需的方式在内部索引项目 是否有一个MooseX扩展可以通过处理程序创建方法来处理这类事情,而不仅仅是将读访问器当作hashref处理并在适当的地方修改它?还是我最好忘记通过方法调用来做这样的事情,然后照原样做Perl 用于多维数据结构的驼鹿特征,perl,multidimensional-array,moose,Perl,Multidimensional Array,Moose,使用Attribute::Native::Trait处理程序可以轻松地将内部变量从对变量的调用分解为对对象的调用。但是,如何处理多个数据结构?我想不出任何方法来处理下面这样的事情,而不使存储成为My::stash::Attribute对象的arrayref,这反过来又包含My::stash::Subattribute对象的arrayref,其中包含一个arrayref My::stash::Instance对象。这包括在我整理数据时,在堆栈的每一层都进行大量的咀嚼和强制数据 是的,我可以将项目存
use strict;
use warnings;
use 5.010;
package My::Stash;
use Moose;
has '_stash' => (is => 'ro', isa => 'HashRef', default => sub { {} });
sub add_item {
my $self = shift;
my ($item) = @_;
push @{$self->_stash->{$item->{property}}{$item->{sub}}}, $item;
}
sub get_items {
my $self = shift;
my ($property, $subproperty) = @_;
return @{$self->_stash->{$property}{$subproperty}};
}
package main;
use Data::Printer;
my $stash = My::Stash->new();
for my $property (qw/foo bar baz/) {
for my $subproperty (qw/fazz fuzz/) {
for my $instance (1 .. 2) {
$stash->add_item({ property => $property, sub => $subproperty, instance => $instance })
}
}
}
p($_) for $stash->get_items(qw/baz fuzz/);
这些都是非常深奥的:
sub add_item {
my $self = shift;
my ($item) = @_;
push @{$self->_stash->{$item->{property}}{$item->{sub}}}, $item;
}
因此,add_item
获取一个hashrefitem
,并将其推送到存储库中的一个数组键上,该数组键由它自己的键属性
和子项
索引
sub get_items {
my $self = shift;
my ($property, $subproperty) = @_;
return @{$self->_stash->{$property}{$subproperty}};
}
相反,get\u item
接受两个参数,一个$property
和一个$subperty
,它检索HoH中数组中的适当元素
因此,以下是使其成为MooseX的关注点:
- 在非魔法散列中没有办法坚持只有散列才是值——这对于trait上的可预测行为是必需的。在您的示例中,如果
解析为标量,您会期望什么\u stash->{$property}
已将其深度硬编码为add_项
和属性
子项
- 返回数组不正确,需要将所有元素推送到堆栈上(返回引用)
->set( [qw/ key1 key2/], 'foo' )
->get( [qw/ key1 key2/] )
如果您的目的地不是阵列,这肯定会使您的工作更轻松:
sub add_item {
my ( $self, $hash ) = @_;
$self->set( [ $hash->{property}, $hash->{subproperty} ], $hash );
}
# get items works as is, just pass in an `ArrayRef`
# ie, `->get([$property, $subproperty])`
当目标是数组而不是散列槽时,我假设您只需要将其构建到trait中一个完全不同的助手,push\u to\u array\u或\u create([$property,$subperty],$value)
。我仍然使用上面指定的虚构的get
helper来检索它<代码>自动删除类型功能是一个非常糟糕的主意
简言之,询问核心开发人员,他们会如何考虑在这种情况下扩展set
和get
,以接受ArrayRefs作为键并采取适当的行动。我无法想象ArrayRef键有一个有用的默认值(我不认为常规的字符串化会太有用)