Provided by: libiterator-simple-perl_0.07-3_all bug

NAME

       Iterator::Simple - Simple iterator and utilities

SYNOPSIS

         use Iterator::Simple;

         sub foo {
           my $max = shift;
           my $i = 0;
           iterator {
             return if $i > $max;
             $i++;
           }
         }

         my $iterator = foo(20); # yields 0,1,2, ..., 19, 20;
         $iterator = imap { $_ + 2 } $iterator; # yields 2,3,4,5, ... ,20,21,22
         $iterator = igrep { $_ % 2 } $iterator; # yields 3,5,7,9, ... ,17,19,21

         # iterable object
         $iterator = iter([qw(foo bar baz)]); # iterator from array ref
         $iterator = iter(IO::File->new($filename)); # iterator from GLOB

         # filters
         $iterator = ichain($itr1, $itr2); # chain iterators;
         $iterator = izip($itr1, $itr2); # zip iterators;
         $iterator = ienumerate $iterator; # add index;

         # general filter
         $iterator = ifilter $iterator, sub {
           return $_ if /^A/;
           return;
         }

         # how to iterate
         while(defined($_ = $iterator->())) {
           print;
         }

         while(defined($_ = $iterator->next)) {
           print;
         }

         while(<iterator>) {
           print;
         }

DESCRIPTION

       Iterator::Simple is yet another general-purpose iterator utilities.

       Rather simple, but powerful and fast iterator.

FUNCTIONS

       Iterator::Simple doesn't export any functions by default. please import them like:

         use Iterator::Simple qw(iter list imap);

       For all functions:

         use Iterator::Simple qw(:all);

       iterator { CODE }
           Iterator constructor. CODE returns a value on each call, and if it is exhausted,
           returns undef. Therefore, you cannot yields undefined value as a meaning value. If you
           want, you could use Iterator module which can do that.

           Generally, you can implement iterator as a closure like:

             use Iterator::Simple qw(iterator);

             sub fibonacci {
               my($s1, $s2, $max) = @_;

               iterator {
                 my $rv;
                 ($rv, $s1, $s2) = ($s1, $s2, $s1 + $s2);
                 return if $rv > $max;
                 return $rv;
               }
             }

             my $iterator = fiboacci(1, 1, 1000);

           You can iterate it in several ways:

           • just call it

               while(defined($_ = $iterator->())) {
                 print "$_\n";
               }

           • "next" method

               while(defined($_ = $iterator->next)) {
                 print "$_\n";
               }

           • <> operator

               while(<$iterator>) {
                 print "$_\n";
               }

       is_iterator($object)
           If $object is an iterator created by Iterator::Simple, returns true.  False otherwise.

       iter($object)
           This function auto detects what $object is, and automatically turns it into an
           iterator. Supported objects are:

           • Iterator made with Iterator::Simple.

           • Object that implements "__iter__" method.

           • Object that overloads '<>' or has "next" method.

           • Object that overloads '&{}'.(as iterator function.)

           • Object that overloads '@{}'.(with "iarray()")

           • ARRAY reference. ("iarray()")

           • CODE reference. (as iterator function.)

           • GLOB reference.

           • nothing ("iter()".) (empty iterator.)

           If it fails to convert, runtime error.

       is_iterable($object)
           return true if $object can be converted with "iter($object)"

       list($object)
           This function converts $object into single array referece.

           • ARRAY reference.

           • GLOB reference.

           • Iterator made with Iterator::Simple.

           • Object that overloads '@{}' operator.

           • Object that implements '__iter__' method.

           • Object that overloads '<>' operator or has "next" method.

           • nothing (i.e. list() returns []);

           If it fails to convert, runtime error.

           Note that after "list($iterator)", that iterator is not usable any more.

       imap { CODE } $iterable
           This is the iterator version of "map". Returns an iterator which yields the value from
           source iterator modified by CODE.

       igrep { CODE } $iterable
           This is the iterator version of "grep". Returns an iterator which yields the value
           from source iterator only when CODE returns true value.

       iflatten $iterable
           When $iterable yields another iterator, iterate it first.

             $subitr = iter([10, 11,12]);
             $source = iter([ 1, 2, $subitr, 4]);

             $flattened = iflatten $source;

             # yields 1, 2, 10, 11, 12, 4.

       ifilter $iterable, sub{ CODE }
           This is the combination of imap, igrep, iflatten. it supports modify (imap) , skip
           (igrep), and inflate (iflatten). but it should be faster than combination of them.

           For example:

             $combination = iflatten
               imap { $_ eq 'baz' ? iter(['whoa', 'who']) : ":$_:" }
               igrep { $_ ne 'bar' }
               iter [ 'foo', 'bar', 'baz', 'fiz' ];

             $itr = iter [ 'foo', 'bar', 'baz', 'fiz' ];
             $filterd = ifilter $itr, sub {
               return if $_ eq 'bar'; #skip
               return iter(['whoa', 'who']) if $_ eq 'baz'; #inflate
               return ":$_:"; # modify
             };

           Both of them will yields ':foo:', 'whoa', 'who', ':fiz:'.

       ichain($iterable, $iterable2, ...)
           This function returns an iterator which chains one or more iterators.  Iterates each
           iterables in order as is, until each iterables are exhausted.

           Example:

             $itr1 = iter(['foo', 'bar', 'baz']);
             $itr2 = iter(['hoge', 'hage']);

             $chained = ichain($itr1, $itr2);

             # yields 'foo', 'bar', 'baz', 'hoge', 'hage'.

       ienumerate($iterable)
           This function returns an iterator yields like:

             $ary = iter(['foo', 'bar', 'baz', ... ]);

             $iter = ienumerate $ary;

             # yields [0, 'foo'], [1, 'bar'], [2, 'baz'], ...

       izip($iterable, $iterable2, ...);
           Accepts one or more iterables, returns an iterator like:

             $animals = iter(['dogs', 'cats', 'pigs']);
             $says = iter(['bowwow', 'mew', 'oink']);

             $zipped = izip($animals, $says);

             # yields ['dogs','bowwow'], ['cats','mew'], ['pigs', 'oink'].

           Note that when one of source iterables is exhausted, zipped iterator will be exhausted
           also.

       islice($iterable, $start, $end, $step)
           Same as islice of itertools in Python. If $end is undef or negative value, it iterates
           source until it is exhausted.  $step defaults to 1. 0 or negative step value is
           prohibited.

             $iter = iter([0,1,2,3,4,5,6,7,8,9,10,11,12]);

             $sliced = islice($iter, 3, 13, 2);

             # yields 3, 5, 7, 9, 11.

       ihead($count, $iterable)
             islice($iterable, 0, $count, 1);

       iskip($count, $iterable)
             islice($iterable, $count, undef, 1);

       iarray($arrayref);
           Turns array reference into an iterator. Used in "iter($arrayref)".  You do not have to
           use this function directly, because "iter($arrayref)" is sufficient.

OO INTERFACE

       Iterator used in Iterator::Simple is just a code reference blessed in
       Iterator::Simple::Iterator. This class implements several method and overloads some
       operators.

       Itrator::Simple::Iterator->new($coderef)
           Just bless $coderef in Iterator::Simple::Iterator and returns it.

       $iterator->next
           Call underlying code.

       $iterator->__iter__
           Returns self. You don't need to use this.

       Overloaded operators.
           • Read filehandle operator '<>'

             Overloading '<>' makes this possible like:

               print while <$iterator>;

           • Pipe.. bit_OR? .. No, pipe!

               $iterator | $coderef1 | $coderef2;

             is equivalent to:

               $iterator->filter($coderef1)->filter($coderef2);

             is equivalent to:

               ifilter(ifilter($iterator, $coderef1), $coderef2);

       $iterator->filter($coderef)
       $iterator->flatten()
       $iterator->chain($another, ..)
       $iterator->zip($another, ..)
       $iterator->enumerate()
       $iterator->slice($start, $end, $step)
       $iterator->head($count)
       $iterator->skip($count)
           For example, $iterator->flatten() is equivalent to "iflatten $iterator".

TIPS

       All iterator transformation function calls "iter" function on all source iterables. So you
       can pass just array reference, GLOB ref, etc.

       These examples completely do the right thing:

         imap { $_ + 2 } [1, 2, 3, ... ];
         ienumerate(\*STDIN);

         # DBIx::Class::ResultSet has 'next' method.
         ifilter $dbic_resultset, sub {CODE};

       You can implement "__iter__" method on your objects in your application.  By doing that,
       your object will be Iterator::Simple friendly :).

       Note that "__iter__" method must return an iterator.

Why Not Iterator.pm

       There is another iterator module in CPAN, named Iterator and Iterator::Util made by Eric
       J. Roode that is great solution.  Why yet another iterator module? The answer is *Speed*.
       You use iterator because you have too many data to manipulate in memory, therefore
       iterator could be called thousands of times, speed is important.

       For this simple example:

         use Iterator::Util qw(iarray imap igrep);

         for(1 .. 100) {
           my $itr = igrep { $_ % 2 } imap { $_ + 2 } iarray([1 .. 1000]);
           my @result;
           while($itr->isnt_exhausted) {
             push @result, $itr->value;
           }
         }

       meanwhile:

         use Iterator::Simple qw(iarray imap igrep);

         for(1 .. 100) {
           my $itr = igrep { $_ % 2 } imap { $_ + 2 } iarray([1 .. 1000]);
           my @result;
           while(defined($_ = $itr->())) {
             push @result, $_;
           }
         }

       Iterator::Simple is about ten times faster!

       That is natural because Iterator::Simple iterator is just a code reference, while
       Iterator.pm iterator is full featured class instance.  But Iterator::Simple is sufficient
       for usual demands.

       One of most downside of Iterator::Simple is, you cannot yields undef value as a meaning
       value, because Iterator::Simple thinks it as a exhausted sign.  If you need to do that,
       you have to yield something which represents undef value.

       Also, Iterator::Simple cannot determine iterator is exhausted until next iteration, while
       Iterator.pm has 'is(nt)_exhausted' method which is useful in some situation.

AUTHOR

       Rintaro Ishizaki <rintaro@cpan.org>

LICENSE

       This library is free software; you can redistribute it and/or modify it under the same
       terms as Perl itself.

SEE ALSO

       • Iterator - Feature rich another iterator class.

       • Iterator::Util - Utilities which uses Iterator. Many of filter functions are from this
         module.