多维数据结构的驼鹿特征



使用Attribute::Native::Trait处理程序很容易将内部变量从对变量的调用分解为对对象的调用。但是,如何处理多个数据结构呢?如果不让stash成为My:: stash::Attribute对象的arrayref,我想不出任何方法来处理下面的事情,而这个对象又包含一个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/);

这些是非常深奥的:

sub add_item {
  my $self = shift;
  my ($item) = @_;
  push @{$self->_stash->{$item->{property}}{$item->{sub}}}, $item;
}

因此,add_item取一个hashref item,并将其压入存储中的数组键,该数组键由propertysub自己的键索引。

sub get_items {
  my $self = shift;
  my ($property, $subproperty) = @_;
  return @{$self->_stash->{$property}{$subproperty}};
}

相反,get_item有两个参数,一个$property和一个$subproperty,它在HoH中检索数组中相应的元素。

所以这里是考虑到使MooseX:

  • 在非magic散列中没有办法坚持只有散列是值——这将是trait上可预测行为所必需的。在您的示例中,如果_stash->{$property}解析为标量,您会期望什么?
  • add_item将其深度硬编码为propertysub
  • 返回数组是不好的,它要求所有的元素被推到堆栈(返回refs)

首先,我不明白为什么一个普通的Moose Hash trait不能同时接受setter和getter的数组引用。

->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_to_array_or_create([$property, $subproperty], $value)中完全不同的helper中。我仍然只是使用上面指定的虚构的get帮助器检索它。auto_deref类型的功能是一个非常糟糕的主意。

简而言之,问问核心开发人员,他们会如何考虑在这种情况下扩展setget,以接受 arrayref 作为键并采取适当的行动。我无法想象有一个有用的默认值ArrayRef键(我不认为常规的字符串化会太有用)。

相关内容

  • 没有找到相关文章

最新更新