2014-02-12 37 views
5

我想从存储在Moose类中的列表中获取元素。该类知道如何填充该列表本身。它有点像迭代器,除了我希望能够重置迭代器,并开始从列表中获取相同的元素,就好像我还没有这样做。我打算叫如下:Moose是否有义务在打电话后再打电话给建筑工?

while(my $slotlist = $class->get_next_slotlist) { 
    # do something with $slotlist 
} 

除此之外,正如我所说,我可能要在以后再次重申了相同的元素:

$class->reset_slotlists; 
while(my $slotlist = $class->get_next_slotlist) { 
    # do something with $slotlist 
} 

我想沿着设计类以下简装(模拟)版本的台词:

package List; 
use Moose; 

has '_data' => (
    traits => [ 'Array' ], 
    is  => 'ro', 
    predicate => 'has_data', 
    lazy  => 1, 
    builder => '_build_data', 
    clearer => 'reset', 
    handles => { 
     next => 'shift', 
    }, 
); 

sub _build_data { [ 'abc', 'def' ] } 

package main; 
use strict; 
use warnings; 
use Test::More; 
use Test::Pretty; 

my $list = List->new; 
ok ! $list->has_data; 
is $list->next, 'abc'; 
is $list->next, 'def'; 
is $list->next, undef; 
is $list->next, undef; 
$list->reset; 
is $list->next, 'abc', 'Moose calls builder again after clearing'; 
is $list->next, 'def'; 
is $list->next, undef; 
is $list->next, undef; 
ok $list->has_data; 

done_testing; 

当我运行此,驼鹿再次调用Builder之后再调用reset()方法(即,更清晰)。我现在的问题是:这种行为有保证吗?该文件没有说。当我输入这个问题时,我也开始怀疑:你认为这是不好的设计吗?我喜欢类似于迭代器的界面,在调用方面非常优雅,并且容易实现,但是这个问题是一个标志那么设计不好?)

+0

您应该在irc.perl.org的#moose上发表意见。负责穆斯的人最了解。 – simbabque

回答

7

是的,如果一个惰性属性已被清除,那么下次调用一个存取器时,该值将被重建。

清算_data本质上就是这样做delete($self->{_data})。或者如果Moose对象是hashrefs,但它们不是hashrefs,它们是对象。 (实际上它们是下面的hashrefs,但是Moose的部分经验是我们应该假装我们不知道这个。)

懒惰属性使用exists($self->{_data})来决定是否需要构建值。

我不认为这是一个糟糕的设计,但如果数组很大,那么保留副本_data以迭代方式销毁shift可能会浪费内存。你可以只保留一个数组的位置,并每次增加它。

更新:你是正确的,这是没有记录得很好。