Reputation: 2410
I have an iterator with this interface: $hit->next_hsp
The current implementation to listify it is:
my @list;
while ( my $hsp = $hit->next_hsp ) {
push( @list, $hsp );
}
Now I'm thinking that there might be better ways to do this in less code. What do you say, stackers?
Upvotes: 6
Views: 219
Reputation: 6070
Don't worry about playing golf, the code you have looks just fine (other than the other answers about using defined
). However, if you find yourself repeating this pattern 2 things come to mind.
The first is obvious, refactor it into a utility function, so that you have my @list = expand($hit).
The second question is a bit deeper - but to me smells more than playing golf. The whole point of iterators is to consume as you need them, so if you find yourself doing this often, are you sure it's really the right thing to do? Perhaps your moving this data outside your own API, so you're constrained to other's choices, but if you have the option of consuming an iterator rather than a list, maybe this will be a cleaner solution.
Upvotes: 3
Reputation: 39158
All iterators I've ever seen return undef
to signify that they are exhausted. Therefore you should write while (defined(my $hsp = $hit->next_hsp))
. The following example demonstrates the fault in the question which tests for truth (aborts at 1) instead of definedness (passes 'liftoff').
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
Upvotes: 5
Reputation: 4700
It entirely depends on the iterator implementation. If next_hsp
is the only available method, then you're doing it right.
Upvotes: 3