在Perl中将迭代器扩展到列表中最优雅的方法是什么?

时间:2010-10-10 18:29:00

标签: perl

我有一个带有这个界面的迭代器:$ hit-> next_hsp

目前实现的目标是:

my @list;
while ( my $hsp = $hit->next_hsp ) {
    push( @list, $hsp );
}

现在我认为可能有更好的方法可以在更少的代码中执行此操作。你怎么说,堆垛机?

3 个答案:

答案 0 :(得分:5)

我见过的所有迭代器都会返回undef来表示它们已经用尽了。因此,您应该写while (defined(my $hsp = $hit->next_hsp))。以下示例演示了问题中的错误,该错误测试了真值(中止为1)而不是定义(通过'升空')。

use 5.010;
my $hit = __PACKAGE__;

sub next_hsp {
    state $i;
    $i++;
    return ['mumble', 4, 3, 2, 1, 0, 'liftoff']->[$i];
}

# insert snippet from question here

答案 1 :(得分:3)

完全取决于迭代器的实现。如果next_hsp是唯一可用的方法,那么你做得对。

答案 2 :(得分:3)

不要担心打高尔夫球,你看到的代码看起来很好(除了关于使用defined的其他答案)。但是,如果你发现自己重复这种模式,我会想到两件事。

第一个很明显,将其重构为实用函数,以便my @list = expand($hit).

第二个问题有点深 - 但对我而言,闻起来不仅仅是打高尔夫球。迭代器的重点是根据需要进行消费,所以如果你发现自己经常这样做,你确定它真的是正确的吗?也许你在自己​​的API之外移动这些数据,所以你受限于其他人的选择,但如果你可以选择使用迭代器而不是列表,那么这可能是一个更清洁的解决方案。