2011-07-14 37 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鍵有一個有用的默認值(我不認爲常規字符串化會太有用。)。