File Coverage

blib/lib/Catmandu/Iterable.pm
Criterion Covered Total %
statement 262 263 99.6
branch 67 72 93.0
condition 26 31 83.8
subroutine 57 57 100.0
pod 34 35 97.1
total 446 458 97.3


line stmt bran cond sub pod time code
1              
2             use Catmandu::Sane;
3 65     65   121218  
  65         143  
  65         433  
4             our $VERSION = '1.2019';
5              
6             use Catmandu::Util qw(
7 65         4554 is_number
8             is_value
9             is_string
10             is_array_ref
11             is_hash_ref
12             is_regex_ref
13             is_same
14             check_positive
15             );
16 65     65   480 use Time::HiRes qw(gettimeofday tv_interval);
  65         134  
17 65     65   417 use Hash::Util::FieldHash qw(fieldhash);
  65         117  
  65         623  
18 65     65   37059 use Role::Tiny;
  65         52501  
  65         3404  
19 65     65   443 use namespace::clean;
  65         142  
  65         469  
20 65     65   12762  
  65         134  
  65         409  
21             # delay loading these because of circular dependency
22             require Catmandu::Iterator;
23             require Catmandu::ArrayIterator;
24              
25             requires 'generator';
26              
27             {
28             # can't use Moo attribute because of circular dependency
29             fieldhash my %_generators;
30              
31             my ($self) = @_;
32             ($_generators{$self} ||= $self->generator)->();
33 9     9 1 1726 }
34 9   66     59  
35             my ($self) = @_;
36             $_generators{$self} = $self->generator;
37             }
38 4     4 1 464 }
39 4         9  
40             my ($self) = @_;
41             my $next = $self->generator;
42             my @a;
43             my $data;
44 87     87 1 8741 while (defined($data = $next->())) {
45 87         802 push @a, $data;
46 87         191 }
47             \@a;
48 87         169 }
49 911         2370  
50             my ($self) = @_;
51 87         1439 my $next = $self->generator;
52             my $n = 0;
53             while ($next->()) {
54             $n++;
55 15     15 1 480 }
56 15         58 $n;
57 15         52 }
58 15         60  
59 1026         1834 my ($self, $exporter) = @_;
60             $exporter->add_many($self);
61 15         132 }
62              
63             my ($self, $start, $total) = @_;
64             $start //= 0;
65 1     1 1 354 Catmandu::Iterator->new(
66 1         4 sub {
67             sub {
68             if (defined $total) {
69             $total || return;
70 6     6 1 42 }
71 6   100     20 state $next = $self->generator;
72             state $data;
73             while (defined($data = $next->())) {
74             if ($start > 0) {
75 13 100       29 $start--;
76 9 100       26 next;
77             }
78 9         37 if (defined $total) {
79 9         42 $total--;
80 9         18 }
81 12 100       40 return $data;
82 4         6 }
83 4         8 return;
84             }
85 8 100       18 }
86 5         9 );
87             }
88 8         30  
89             my ($self, $sub) = @_;
90 1         5 my $next = $self->generator;
91             my $n = 0;
92 6     6   23 my $data;
93 6         55 while (defined($data = $next->())) {
94             $sub->($data);
95             $n++;
96             }
97 5     5 1 85 $n;
98 5         80 }
99 5         16  
100 5         11 my ($self, $sub) = @_;
101 5         14 my $next = $self->generator;
102 9         35 my $n = 0;
103 8         19 my $data;
104             while (defined($data = $next->())) {
105 4         30 $sub->($data) || last;
106             $n++;
107             }
108             $n;
109 1     1 0 2 }
110 1         3  
111 1         2 my ($self, $sub) = @_;
112 1         2 Catmandu::Iterator->new(
113 1         3 sub {
114 2 100       4 sub {
115 1         529 state $next = $self->generator;
116             state $data;
117 1         526 if (defined($data = $next->())) {
118             $sub->($data);
119             return $data;
120             }
121 10     10 1 708 return;
122             }
123             }
124             );
125 30         97 }
126 30         57  
127 30 100       59 my ($self, $n, $sub) = @_;
128 20         70 check_positive($n);
129 20         67 Catmandu::Iterator->new(
130             sub {
131 10         42 sub {
132             state $next = $self->generator;
133 10     10   68 state $data;
134 10         82 state $i = 0;
135             if (defined($data = $next->())) {
136             if (++$i == $n) {
137             $sub->($data);
138 3     3 1 697 $i = 0;
139 3         10 }
140             return $data;
141             }
142             return;
143 22         24 }
144 22         34 }
145 22         21 );
146 22 100       27 }
147 20 100       64  
148 8         14 my ($self, $sub) = @_;
149 8         17 my $next = $self->generator;
150             my $data;
151 20         30 while (defined($data = $next->())) {
152             $sub->($data) && return 1;
153 2         9 }
154             return 0;
155 2     2   8 }
156 2         17  
157             my ($self, $sub) = @_;
158             my $next = $self->generator;
159             my $n = 0;
160 8     8 1 18 my $data;
161 8         24 while (defined($data = $next->())) {
162 8         53 $sub->($data) && ++$n > 1 && return 1;
163 8         17 }
164 21 100       459 return 0;
165             }
166 4         260  
167             my ($self, $sub) = @_;
168             my $next = $self->generator;
169             my $data;
170 2     2 1 5 while (defined($data = $next->())) {
171 2         6 $sub->($data) || return 0;
172 2         15 }
173 2         4 return 1;
174 2         4 }
175 5 100 100     33  
176             my ($self, $sub) = @_;
177 1         9 Catmandu::Iterator->new(
178             sub {
179             sub {
180             state $next = $self->generator;
181 3     3 1 8 state @buff;
182 3         9 @buff = $sub->($next->() // return) unless @buff;
183 3         23 shift @buff;
184 3         7 }
185 5 100       29 }
186             );
187 2         23 }
188              
189             my $self = shift;
190             my $memo_set = @_ > 1;
191 27     27 1 95 my $sub = pop;
192             my $memo = shift;
193             my $next = $self->generator;
194             my $data;
195 803         1721 while (defined($data = $next->())) {
196 803         1228 if ($memo_set) {
197 803 100 100     2450 $memo = $sub->($memo, $data);
198 778         3253 }
199             else {
200 26     26   106 $memo = $data;
201 27         203 $memo_set = 1;
202             }
203             }
204             $memo;
205 26     26 1 128 }
206 26         46  
207 26         34 $_[0]->generator->();
208 26         36 }
209 26         227  
210 26         108 $_[0]->slice(1);
211 26         50 }
212 95 100       287  
213 94         175 $_[0]->slice(0, $_[1]);
214             }
215              
216 1         2 {
217 1         52 my $to_sub = sub {
218             my ($arg1, $arg2) = @_;
219              
220 26         512 if (is_string($arg1)) {
221             if (is_regex_ref($arg2)) {
222             return sub {
223             is_hash_ref($_[0]) || return 0;
224 12     12 1 176 my $val = $_[0]->{$arg1};
225             is_value($val) && $val =~ $arg2;
226             };
227             }
228 2     2 1 644 if (is_array_ref($arg2)) {
229             return sub {
230             is_hash_ref($_[0]) || return 0;
231             is_value(my $val = $_[0]->{$arg1}) || return 0;
232 2     2 1 6 for my $v (@$arg2) {
233             return 1 if $val eq $v;
234             }
235             0;
236             };
237             }
238             return sub {
239             is_hash_ref($_[0]) || return 0;
240             my $val = $_[0]->{$arg1};
241             is_value($val) && $val eq $arg2;
242             };
243             }
244              
245             if (is_regex_ref($arg1)) {
246             return sub {
247             my $val = $_[0];
248             is_value($val) && $val =~ $arg1;
249             };
250             }
251              
252             $arg1;
253             };
254              
255             my $self = shift;
256             my $sub = $to_sub->(@_);
257             my $next = $self->generator;
258             my $data;
259             while (defined($data = $next->())) {
260             $sub->($data) && return $data;
261             }
262             return;
263             }
264              
265             my $self = shift;
266             my $sub = $to_sub->(@_);
267             Catmandu::Iterator->new(
268             sub {
269             sub {
270             state $next = $self->generator;
271             state $data;
272             while (defined($data = $next->())) {
273             $sub->($data) && return $data;
274             }
275 4     4 1 8 return;
276 4         8 }
277 4         12 }
278 4         28 );
279 4         8 }
280 8 100       40  
281              
282 1         9 my $self = shift;
283             my $sub = $to_sub->(@_);
284             Catmandu::Iterator->new(
285             sub {
286 10     10 1 18 sub {
287 10         33 state $next = $self->generator;
288             state $data;
289             while (defined($data = $next->())) {
290             $sub->($data) || return $data;
291 27         65 }
292 27         73 return;
293 27         44 }
294 31 100       115 }
295             );
296 10         46 }
297             };
298 10     10   32  
299 10         57 my ($self, $cmp) = @_;
300             if (!defined $cmp) {
301             Catmandu::ArrayIterator->new([sort @{$self->to_array}]);
302 4     4 1 12 }
303             elsif (ref $cmp) {
304             Catmandu::ArrayIterator->new(
305 13     13 1 27 [sort {$cmp->($a, $b)} @{$self->to_array}]);
306 13         41 }
307             else {
308             # TODO: use Schwartzian transform for more complex key
309             Catmandu::ArrayIterator->new(
310 36         284 [sort {$a->{$cmp} cmp $b->{$cmp}} @{$self->to_array}]);
311 36         96 }
312 36         63 }
313 35 100       111  
314             my ($self, $key) = @_;
315 11         69 $self->map(
316             sub {
317 12     12   74 $_[0]->{$key};
318 13         58 }
319             );
320             }
321              
322             my ($self, $method, @args) = @_;
323 3     3 1 9 $self->map(
324 3 100       10 sub {
    100          
325 1         3 $_[0]->$method(@args);
  1         3  
326             }
327             );
328             }
329 1         2  
  3         8  
  1         4  
330              
331             my ($self, $data) = @_;
332             $self->any(
333             sub {
334 1         2 is_same($data, $_[0]);
  2         9  
  1         3  
335             }
336             );
337             }
338              
339 2     2 1 15 my ($self, $size) = @_;
340             Catmandu::Iterator->new(
341             sub {
342 6     6   18 sub {
343             state $next = $self->generator;
344 2         15  
345             my $group = [];
346              
347             for (my $i = 0; $i < $size; $i++) {
348 5     5 1 45 push @$group, $next->() // last;
349             }
350              
351 16     16   726 unless (@$group) {
352             return;
353 5         19 }
354              
355             Catmandu::ArrayIterator->new($group);
356 4     4 1 14 }
357             }
358             );
359 6     6 1 13 }
360              
361             my @iterators = @_;
362 17     17   40 Catmandu::Iterator->new(
363             sub {
364 6         24 sub {
365             state @generators;
366             state $n = @iterators;
367             state $i = 0;
368 3     3 1 7 while ($n) {
369             $i = 0 if $i == $n;
370             my $next = $generators[$i] ||= $iterators[$i]->generator;
371             if (defined(my $data = $next->())) {
372 17         26 $i++;
373             return $data;
374 17         35 }
375             else {
376 17         30 splice @generators, $i, 1;
377 24   100     55 $n--;
378             }
379             }
380 17 100       68 return;
381 3         12 }
382             }
383             );
384 14         31 }
385              
386 3     3   16 my ($self, $sub) = @_;
387 3         16 $self->reduce(
388             undef,
389             sub {
390             my ($memo, $data) = @_;
391 4     4 1 65 my $val = defined $sub ? $sub->($data) : $data;
392             return $val > $memo ? $val : $memo
393             if is_number($memo) && is_number($val);
394             return $memo if is_number($memo);
395 26         26 return $val if is_number($val);
396 26         27 return;
397 26         26 }
398 26         39 );
399 30 100       40 }
400 30   66     52  
401 30 100       92 my ($self, $sub) = @_;
402 22         65 $_[0]->reduce(
403 22         38 undef,
404             sub {
405             my ($memo, $data) = @_;
406 8         26 my $val = defined $sub ? $sub->($data) : $data;
407 8         20 return $val < $memo ? $val : $memo
408             if is_number($memo) && is_number($val);
409             return $memo if is_number($memo);
410 4         8 return $val if is_number($val);
411             return;
412 4     4   13 }
413 4         18 );
414             }
415              
416             my ($self) = @_;
417 5     5 1 10 $self->tap(
418             sub {
419             state $n = 0;
420             state $t = [gettimeofday];
421 12     12   17 if (++$n % 100 == 0) {
422 12 100       20 printf STDERR "added %9d (%d/sec)\n", $n,
423 12 50 100     54 $n / tv_interval($t);
    100          
424             }
425 7 100       14 }
426 5 100       13 );
427 3         5 }
428              
429 5         25 my ($self, %opts) = @_;
430             $opts{header} //= 1;
431             $opts{col_sep} //= " | ";
432             my @cols = $opts{cols} ? @{$opts{cols}} : ();
433 5     5 1 10 my @col_lengths = map length, @cols;
434              
435             my $rows = $self->map(
436             sub {
437 12     12   18 my $data = $_[0];
438 12 100       30 my $row = [];
439 12 50 100     80 for (my $i = 0; $i < @cols; $i++) {
    100          
440             my $col = $data->{$cols[$i]} // "";
441 7 100       19 my $len = length $col;
442 5 100       13 $col_lengths[$i] = $len if $len > $col_lengths[$i];
443 3         7 push @$row, $col;
444             }
445 5         24 $row;
446             }
447             )->to_array;
448              
449 6     6 1 14 my @indices = 0 .. @cols - 1;
450             my $pattern
451             = join($opts{col_sep}, map {"%-$col_lengths[$_]s"} @indices) . "\n";
452 14     14   21  
453 14         39 if ($opts{header}) {
454 14 50       59 printf $pattern, @cols;
455 0         0 my $sep = $opts{col_sep};
456             $sep =~ s/[^|]/-/g;
457             print join($sep, map {'-' x $col_lengths[$_]} @indices) . "\n";
458             }
459 6         54 for my $row (@$rows) {
460             printf $pattern, @$row;
461             }
462             }
463 6     6 1 30  
464 6   50     34 my ($self, $sub) = @_;
465 6   50     34 Catmandu::Iterator->new(
466 6 50       17 sub {
  6         18  
467 6         24 sub {
468             state $next = $self->generator;
469             my $data = $next->() // return;
470             $sub->($data) && return;
471 717     717   17984 $data;
472 717         1468 }
473 717         2589 }
474 2151   100     5185 );
475 2151         3290 }
476 2151 100       3519  
477 2151         4776 my ($self) = @_;
478             my $next = $self->generator;
479 717         1773 my $run = 0;
480             while (defined($next->())) {
481 6         64 $run ||= 1;
482             }
483 6         90 $run;
484             }
485 6         19  
  18         60  
486             1;
487 6 50       32  
488 6         56  
489 6         175 =pod
490 6         33  
491 6         16 =head1 NAME
  18         53  
492              
493 6         75 Catmandu::Iterable - Base role for all iterable Catmandu classes
494 717         12197  
495             =head1 SYNOPSIS
496              
497             # Create an example Iterable using the Catmandu::Importer::Mock class
498             my $it = Catmandu::Importer::Mock->new(size => 10);
499 2     2 1 5  
500             my $array_ref = $it->to_array;
501             my $num = $it->count;
502              
503 5         10 # Loop functions
504 5   50     20 $it->each(sub { print shift->{n} });
505 5 100       20  
506 3         16 my $item = $it->first;
507              
508 2     2   9 $it->rest
509 2         9 ->each(sub { print shift->{n} });
510              
511             $it->slice(3,2)
512             ->each(sub { print shift->{n} });
513 5     5 1 8  
514 5         11 $it->take(5)
515 5         20 ->each(sub { print shift->{n} });
516 5         12  
517 24   100     49 $it->group(5)
518             ->each(sub { printf "group of %d items\n" , shift->count});
519 5         27  
520             $it->tap(\&logme)->tap(\&printme)->tap(\&mailme)
521             ->each(sub { print shift->{n} });
522              
523             my $titles = $it->pluck('title')->to_array;
524              
525             # Select and loop
526             my $item = $it->detect(sub { shift->{n} > 5 });
527              
528             $it->select(sub { shift->{n} > 5})
529             ->each(sub { print shift->{n} });
530              
531             $it->reject(sub { shift->{n} > 5})
532             ->each(sub { print shift->{n} });
533              
534             # Boolean
535             if ($it->any(sub { shift->{n} > 5}) {
536             .. at least one n > 5 ..
537             }
538              
539             if ($it->many(sub { shift->{n} > 5}) {
540             .. at least two n > 5 ..
541             }
542              
543             if ($it->all(sub { shift->{n} > 5}) {
544             .. all n > 5 ..
545             }
546              
547             # Modify and summary
548             my $it2 = $it->map(sub { shift->{n} * 2 });
549              
550             my $sum = $it2->reduce(0,sub {
551             my ($prev,$this) = @_;
552             $prev + $this;
553             });
554              
555             my $it3 = $it->group(2)->invoke('to_array');
556              
557             # Calculate maximum of 'n' field
558             my $max = $it->max(sub {
559             shift->{n};
560             });
561              
562             # Calculate minimum of 'n' field
563             my $in = $it->min(sub {
564             shift->{n};
565             });
566              
567             =head1 DESCRIPTION
568              
569             The Catmandu::Iterable class provides many list methods to Iterators such as Importers and
570             Exporters. Most of the methods are lazy if the underlying datastream supports it. Beware of
571             idempotence: many iterators contain state information and calls will give different results on
572             a second invocation.
573              
574             =head1 METHODS
575              
576             =head2 to_array
577              
578             Return all the items in the iterator as an array ref.
579              
580             =head2 count
581              
582             Return the count of all the items in the iterator.
583              
584             =head2 add_to
585              
586             Add all items in the iterator to a L<Catmandu::Exporter>. Returns a true value
587             when the exportwas successful or undef on error.
588              
589             =head3 LOOPING
590              
591             =head2 each(\&callback)
592              
593             For each item in the iterator execute the callback function with the item as
594             first argument. Returns the number of items in the iterator.
595              
596             =head2 first
597              
598             Return the first item from the iterator.
599              
600             =head2 rest
601              
602             Returns an iterator containing everything except the first item.
603              
604             =head2 slice($index,$length)
605              
606             Returns an new iterator starting at the item at C<$index> returning at most <$length> items.
607              
608             =head2 take($num)
609              
610             Returns an iterator with the first C<$num> items.
611              
612             =head2 group($num)
613              
614             Splits the iterator into new iterators each containing C<$num> items.
615              
616             $it->group(500)->each(sub {
617             my $group_it = $_[0];
618             $group_it->each(sub {
619             my $item = $_[0];
620             # ...
621             });
622             });
623              
624             Note that the group iterators load their items in memory. The last group
625             iterator will contain less than C<$num> item unless the item count is divisible
626             by C<$num>.
627              
628             =head2 interleave(@iterators)
629              
630             Returns an iterator which returns the first item of each iterator then the
631             second of each and so on.
632              
633             =head2 contains($data)
634              
635             Alias for C<includes>.
636              
637             =head2 includes($data)
638              
639             return true if any item in the collection is deeply equal to C<$data>.
640              
641             =head2 tap(\&callback)
642              
643             Returns a copy of the iterator and executing callback on each item. This method works
644             like the Unix C<tee> command. Use this command to peek into an iterable while it is
645             processing results. E.g. you are writing code to process an iterable and wrote
646             something like:
647              
648             $it->each(sub {
649             # Very complicated routine
650             ...
651             });
652              
653             Now you would like to benchmark this piece of code (how fast are we processing).
654             This can be done by tapping into the iterator and calling a 'benchmark' subroutine
655             in your program that for instance counts the number of items divided by the
656             execution time.
657              
658             $it->tap(\&benchmark)->each(sub {
659             # Very complicated routine
660             ...
661             });
662              
663             sub benchmark {
664             my $item = shift;
665             $start ||= time;
666             $count++;
667              
668             printf "%d recs/sec\n" , $count/(time - $start + 1) if $count % 100 == 0;
669             }
670              
671             Note that the C<benchmark> method already implements this common case.
672              
673             =head2 every($num, \&callback)
674              
675             Similar to C<tap>, but only calls the callback every C<$num> times. Useful for
676             benchmarking and sampling.
677              
678             =head2 detect(\&callback)
679              
680             Returns the first item for which callback returns a true value.
681              
682             =head2 detect(qr/..../)
683              
684             If the iterator contains STRING values, then return the first item which matches the
685             regex.
686              
687             =head2 detect($key => $val)
688              
689             If the iterator contains HASH values, then return the first item where the value of
690             C<$key> is equal to C<$val>.
691              
692             =head2 detect($key => qr/..../)
693              
694             If the iterator contains HASH values, then return the first item where the value of
695             C<$key> matches the regex.
696              
697             =head2 detect($key => [$val, ...])
698              
699             If the iterator contains HASH values, then return the first item where the value of
700             C<$key> is equal to any of the values given.
701              
702             =head2 pluck($key)
703              
704             Return an iterator that only contains the values of the given C<$key>.
705              
706             =head2 select(\&callback)
707              
708             Returns an iterator containing only items item for which the callback returns a true value.
709              
710             =head2 select(qr/..../)
711              
712             If the iterator contains STRING values, then return each item which matches the regex.
713              
714             =head2 select($key => $val)
715              
716             If the iterator contains HASH values, then return each item where the value of
717             C<$key> is equal to C<$val>.
718              
719             =head2 select($key => qr/..../)
720              
721             If the iterator contains HASH values, then return each item where the value of C<$key>
722             matches the regex.
723              
724             =head2 select($key => [$val, ...])
725              
726             If the iterator contains HASH values, then return each item where the value of
727             C<$key> is equal to any of the vals given.
728              
729             =head2 grep( ... )
730              
731             Alias for C<select( ... )>.
732              
733             =head2 reject(\&callback)
734              
735             Returns an iterator containing each item for which callback returns a false value.
736              
737             =head2 reject(qr/..../)
738              
739             If the iterator contains STRING values, then reject every item except those
740             matching the regex.
741              
742             =head2 reject($key => qr/..../)
743              
744             If the iterator contains HASH values, then reject every item for where the value of C<$key>
745             DOESN'T match the regex.
746              
747             =head2 reject($key => $val)
748              
749             If the iterator contains HASH values, then return each item where the value of
750             C<$key> is NOT equal to C<$val>.
751              
752             =head2 reject($key => [$val, ...])
753              
754             If the iterator contains HASH values, then return each item where the value of
755             C<$key> is NOT equal to any of the values given.
756              
757             =head2 sorted
758              
759             Returns an iterator with items sorted lexically. Note that sorting requires
760             memory because all items are buffered in a L<Catmandu::ArrayIterator>.
761              
762             =head2 sorted(\&callback)
763              
764             Returns an iterator with items sorted by a callback. The callback is expected to
765             returns an integer less than, equal to, or greater than C<0>. The following code
766             snippets result in equal arrays:
767              
768             $iterator->sorted(\&callback)->to_array
769             [ sort \&callback @{ $iterator->to_array } ]
770              
771             =head2 sorted($key)
772              
773             Returns an iterator with items lexically sorted by a key. This is equivalent to
774             sorting with the following callback:
775              
776             $iterator->sorted(sub { $_[0]->{$key} cmp $_[1]->{$key} })
777              
778             =head3 EXTERNAL ITERATOR
779              
780             L<Catmandu::Iterable> behaves like an internal iterator. C<next> and C<rewind>
781             allow you to use it like an external iterator.
782              
783             =head2 next
784              
785             Each call to C<next> will return the next item until the iterator is exhausted,
786             then it will keep returning C<undef>.
787              
788             while (my $data = $it->next) {
789             # do stuff
790             }
791              
792             $it->next; # returns undef
793              
794             =head2 rewind
795              
796             Rewind the external iterator to the first item.
797              
798             $it->next; # => {n => 1}
799             $it->next; # => {n => 2}
800             $it->next; # => {n => 3}
801             $it->rewind
802             $it->next; # => {n => 1}
803              
804             Note the the iterator must support this behavior. Many importers are not
805             rewindable.
806              
807             =head3 BOOLEAN FUNCTIONS
808              
809             =head2 any(\&callback)
810              
811             Returns true if at least one item generates a true value when executing callback.
812              
813             =head2 many(\&callback)
814              
815             Alias for C<many>.
816              
817             =head2 many(\&callback)
818              
819             Returns true if at least two items generate a true value when executing callback.
820              
821             =head2 all(\&callback)
822              
823             Returns true if all the items generate a true value when executing callback.
824              
825             =head3 MAP & REDUCE
826              
827             =head2 map(\&callback)
828              
829             Returns a new iterator containing for each item the result of the callback. If
830             the callback returns multiple or no items, the resulting iterator will grow or
831             shrink.
832              
833             =head2 reduce([$start],\&callback)
834              
835             For each item in the iterator execute C<&callback($prev,$item)> where C<$prev> is the
836             optional C<$start> value or the result of the previous call to callback. Returns the
837             final result of the callback function.
838              
839             =head2 invoke($name)
840              
841             Returns an interator were the method C<$name> is called on every object in the iterable.
842             This is a shortcut for C<$it->map(sub { $_[0]->$name })>.
843              
844             =head2 max()
845              
846             Returns the maximum of an iterator containing only numbers.
847              
848             =head2 max(\&callback)
849              
850             Returns the maximum of the numbers returned by executing callback.
851              
852             =head2 min()
853              
854             Returns the minimum of an iterator containing only numbers.
855              
856             =head2 min(\&callback)
857              
858             Returns the minimum of the numbers returned by executing callback.
859              
860             =head2 benchmark()
861              
862             Prints the number of records processed per second to STDERR.
863              
864             =head2 format(cols => ['key', ...], col_sep => ' | ', header => 1|0)
865              
866             Print the iterator data formatted as a spreadsheet like table. Note that this
867             method will load the whole dataset in memory to calculate column widths. See
868             also L<Catmandu::Exporter::Table> for a more elaborated method of printing
869             iterators in tabular form.
870              
871             =head2 stop_if(\&callback)
872              
873             Returns a new iterator thats stops processing if the callback returns false.
874              
875             # stop after encountering 3 frobnitzes
876             my $frobnitzes = 0;
877             $iterator->stop_if(sub {
878             my $rec = shift;
879             $frobnitzes++ if $rec->{title} =~ /frobnitz/;
880             $frobnitzes > 3;
881             })->each(sub {
882             my $rec = shift;
883             ...
884             });
885              
886             =head2 run
887              
888             Simply invokes the iterator and returns 1 if any records were processed, 0 otherwise.
889              
890             $it = $it->tap(sub {
891             # do something
892             });
893             $it = $it->tap(sub {
894             # do another thing
895             });
896             $it->run
897              
898             print 'not empty' if $it->run;
899              
900             =head1 SEE ALSO
901              
902             L<Catmandu::Iterator>.
903              
904             =cut