What is the most elegant way in Perl to extend an iterator to a list?

I have an iterator with this interface: $ hit-> next_hsp

The current implementation for listing it:

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

Now I think there may be better ways to do this with less code. What do you say stackers?

+6
perl
source share
3 answers

It completely depends on the iterator implementation. If next_hsp is the only method available, then you are doing it right.

+3
source share

All iterators I've ever seen return undef to show that they are exhausted. Therefore, you should write while (defined(my $hsp = $hit->next_hsp)) . The following example demonstrates an error in a question that checks the truth (breaks in 1) instead of determining (passes a "shutdown").

 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 
+5
source share

Don't worry about golf, the code you look just fine (apart from other answers about using defined ). However, if you find yourself repeating this pattern, everything comes to mind.

The first is, obviously, reorganize it into a utility function, so you have my @list = expand($hit).

The second question is a little deeper - but I like it better than playing golf. The whole point of iterators is to consume them as needed, so if you do this often, are you sure this is really right? Perhaps you are moving this data outside of your own API, so you are limited by other options, but if you have the option of using an iterator rather than a list, this might be a cleaner solution.

+3
source share

All Articles