2011-07-14 34 views
3

使用Attribute :: Native :: Trait处理程序可以很容易地处理从变量调用到对象调用的内部变量。但是,你如何处理多个数据结构?我想不出任何方式来处理像下面这样的东西,而不需要存储My :: Stash :: Attribute对象的arrayref,而这个对象又包含My :: Stash :: Subattribute对象的arrayref,它包含一个arrayref My :: Stash :: Instance对象。这包括大量的搜集和强制每个级别的数据,因为我把事情搞清楚了。用于多维数据结构的驼鹿特征

是的,我可以将项目作为平面数组存储,然后在每次读取时对其进行grep,但在频繁读取的情况下,大多数调用是读取,对大量数组项进行grepping是很多处理每一次阅读都只是以需要的方式索引内部项目。

是否有一个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/); 

回答

1

这些都是很深奥:

sub add_item { 
    my $self = shift; 
    my ($item) = @_; 

    push @{$self->_stash->{$item->{property}}{$item->{sub}}}, $item; 
} 

所以add_item需要一个hashref item,并将其推到在藏匿通过它自己的钥匙property,并sub索引的数组键。

sub get_items { 
    my $self = shift; 
    my ($property, $subproperty) = @_; 

    return @{$self->_stash->{$property}{$subproperty}}; 
} 

相反地,get_item采用两个参数,一个$property$subproperty和它检索在一个环比一个阵列的相应的元件。

所以这里的问题纳入使它MooseX:

  • 有在非幻散没办法坚持,只有散列值 - 这将需要对该性状预测的行为。正如你的例子,如果_stash->{$property}解析为标量,你会期待什么。
  • add_item它的深度硬编码为propertysub
  • 返回数组是坏的,它要求所有的元素被压入堆栈(返程裁判)

现在首先,我不明白为什么一个普通驼鹿散列特征无法接受阵列裁判对于二传手和获得者来说都是如此。

->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])` 

当涉及到具有目的地是不是一个哈希位置的数组,我想你” d只需将其建成一个完全不同的帮手即push_to_array_or_create([$property, $subproperty], $value)。我仍然只是用上面指定的虚构的get帮手检索它。 auto_deref类型的功能是一个非常糟糕的主意。

总之问什么,他们会考虑在这方面扩大setget接受ArrayRefs密钥和采取适当的行动核心开发人员。我无法想象ArrayRef键有一个有用的默认值(我不认为常规字符串化会太有用。)。