File Coverage

blib/lib/Data/Eacherator.pm
Criterion Covered Total %
statement 26 27 96.3
branch 5 6 83.3
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 40 42 95.2


line stmt bran cond sub pod time code
1             package Data::Eacherator;
2              
3 1     1   34072 use strict;
  1         3  
  1         38  
4 1     1   5 use warnings;
  1         3  
  1         31  
5              
6 1     1   6 use base qw(Exporter);
  1         7  
  1         114  
7 1     1   6 use vars qw(@EXPORT_OK $VERSION);
  1         1  
  1         61  
8              
9 1     1   5 use Carp;
  1         2  
  1         287  
10              
11             $VERSION = "0.01";
12             @EXPORT_OK = qw(eacherator);
13              
14             =head1 NAME
15              
16             Data::Eacherator - simple each-like iterator generator for hashes and arrays
17              
18             =head1 SYNOPSIS
19              
20             my $iter = eacherator($hash_or_array);
21              
22             while (my ($k, $v) = $iter->()) {
23             # ...
24             }
25              
26             =head1 DESCRIPTION
27              
28             This module is designed as a simple drop-in replacement for "each" on
29             those occasions when you need to iterate over a hash I an array.
30              
31             That is, if C<$data> is a hash, and you're happily doing something
32             like:
33              
34             while (my ($k, $v) = each %$data) {
35             # ...
36             }
37              
38             but then decide that you also want to loop over C<$data> in the event
39             that it's an array, you can do:
40              
41             my $iter = eacherator($data);
42              
43             while (my ($k, $v) = $iter->()) {
44             # ...
45             }
46              
47             (You may wish to use this package if, for example, you have a module
48             that happily iterates over a hash, but then discover that you also
49             need to iterate over an "ordered" hash--in this case you can just
50             switch curly brackets to square brackets and use C to
51             generate a drop-in replacement for each.)
52              
53             =head1 FUNCTIONS
54              
55             =over 4
56              
57             =item $iter_fn = eacherator($hash_or_array_ref)
58              
59             Returns a function (closure) that behaves like "each".
60              
61             =back
62              
63             =head1 PERFORMANCE
64              
65             Not tested; it's probably quite a bit slower than regular "each" on
66             hashes, though.
67              
68             =head1 SEE ALSO
69              
70             If you need something more sophisticated, or something with
71             similar--but different--behaviour, try C,
72             C, C or C. (All of
73             these generate iterators (some with more each-like semantics than
74             others), but none are indifferent as to whether they receive a hash
75             or array.)
76              
77             Depending on what you're trying to do, C may also be
78             useful.
79              
80             =head1 AUTHOR
81              
82             Michael Stillwell
83              
84             =cut
85              
86             sub eacherator {
87 7     7 1 2032 my ($data) = @_;
88            
89 7 100       24 if (ref($data) eq "HASH") {
    50          
90             return sub {
91 10     10   2333 each %$data
92 2         10 };
93             }
94              
95             elsif (ref($data) eq "ARRAY") {
96 5         8 my $i = 0;
97             return sub {
98 22 100   22   5142 if (@$data >= $i+2) {
99 12         12 $i += 2;
100 12         33 return ($data->[$i-2], $data->[$i-1])
101             }
102             else {
103 10         12 $i = 0;
104 10         20 return ();
105             }
106 5         22 };
107             }
108            
109 0           else { croak "error: can't iterate over something that's not a HASH or ARRAY" }
110             }
111              
112             1;