多维数据结构的驼鹿特征
使用 Attribute::Native::Trait 处理程序可以轻松地将内部变量的处理从对变量的调用分解为对对象的调用。但是,如何处理多种数据结构呢?我想不出任何方法来处理类似下面的事情,而不使存储成为 My::Stash::Attribute 对象的 arrayref,而 My::Stash::Attribute 对象又包含 My::Stash::Subattribute 对象的 arrayref,其中包含 arrayref My::Stash::Instance 对象。这包括在我整理数据时对堆栈中每一层的数据进行大量的修改和强制。
是的,我可以将这些项目存储为平面数组,然后在每次读取时对其进行 grep,但是在频繁读取且大多数调用都是读取的情况下,对大量数组项进行 grep 需要大量处理每次读取而不是仅仅处理以所需的方式在内部对项目进行索引。
是否有 MooseX 扩展可以通过处理程序创建方法来处理此类事情,而不是仅仅将读取访问器视为 hashref 并就地修改它?或者我最好忘记通过方法调用做这样的事情并按原样做?
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/);
Breaking out handling an internal variable from calls on the variable into calls on the object is easy using the Attribute::Native::Trait handlers. However, how do you deal with multiple data structures? I can't think of any way to handle something like the below without making the stash an arrayref of My::Stash::Attribute objects, which in turn contain an arrayref of My::Stash::Subattribute objects, which contains an arrayref My::Stash::Instance objects. This includes a lot of munging and coercing the data each level down the stack as I sort things out.
Yes, I can store the items as a flat array and then grep it on every read, but in a situation with frequent reads and that most calls are reads, grepping against a large list of array items is a lot of processing every read vs just indexing the items internally in the way needed.
Is there a MooseX extension that can handle this sort of thing via handlers creating methods, instead of just treating the read accessor as the hashref it is and modifying it in place? Or am I just best off forgetting about doing things like this via method call and just doing it as-is?
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/);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些非常深奥:
因此
add_item
接受一个 hashrefitem
,并将其推送到 stash 中由它自己的键索引的数组键属性
和子
。相反,
get_item
采用两个参数,一个$property
和一个$subproperty
,它检索 HoH 中数组中的适当元素。因此,MooseX 的关注点如下:
_stash->{$property}
解析为标量,您会期望什么。add_item
将其深度硬编码为property
和sub
。现在首先,我不明白为什么常规 Moose Hash 特征不能接受 setter 和 getter 的数组引用。
如果您的目的地不是一个数组,这肯定会让您的工作变得更容易:
当谈到让目的地是一个数组而不是一个哈希槽时,我认为您只需将其构建到特征中的一个完全不同的帮助器中,
push_to_array_or_create([$property, $subproperty], $value)
。我仍然会使用上面指定的虚构的get
帮助程序来检索它。auto_deref
类型的功能是一个非常糟糕的主意。简而言之,询问核心开发人员,他们会如何看待在此上下文中扩展
set
和get
以接受 ArrayRefs 作为键并采取适当的操作。我无法想象 ArrayRef 键有一个有用的默认值(我认为常规字符串化不会太有用。)。These are very esoteric:
So
add_item
takes an hashrefitem
, and pushes it onto an array key in stash indexed by it's own keysproperty
, andsub
.Conversely,
get_item
takes two arguments, a$property
and a$subproperty
and it retrieves the appropriate elements in a Array in a HoH.So here are the concerns into making it MooseX:
_stash->{$property}
resolved to a scalar.add_item
has it's depth hardcoded toproperty
andsub
.Now firstly, I don't see why a regular Moose Hash trait couldn't accept array refs for both the setter and getter.
This would certainly make your job easier, if your destination wasn't an array:
When it comes to having the destination be an array than a hash slot, I assume you'd just have to build that into a totally different helper in the trait,
push_to_array_or_create([$property, $subproperty], $value)
. I'd still just retrieve it with the fictionalget
helper specified above.auto_deref
type functionality is a pretty bad idea.In short ask a core developer on what they would think about extending
set
andget
in this context to accept ArrayRefs as keys and act appropriately. I can't imagine there is a useful default for ArrayRef keys (I don't think regular stringification would be too useful.).