File Coverage

blib/lib/Iterator/Paged.pm
Criterion Covered Total %
statement 20 25 80.0
branch 4 4 100.0
condition n/a
subroutine 6 8 75.0
pod 4 5 80.0
total 34 42 80.9


line stmt bran cond sub pod time code
1              
2             package Iterator::Paged;
3              
4 2     2   1968 use strict;
  2         6  
  2         68  
5 2     2   12 use warnings 'all';
  2         4  
  2         717  
6              
7             our $VERSION = '1.001';
8              
9              
10             #==============================================================================
11             sub new
12             {
13 1     1 0 65741 my ($class, %args) = @_;
14            
15 1         7 my $s = bless {
16             data => [ ],
17             page_number => 0,
18             idx => 0,
19             %args,
20             }, $class;
21 1         7 $s->_init;
22 1         5 return $s;
23             }# end new()
24              
25 1     1   2 sub _init { }
26              
27              
28             #==============================================================================
29             # Default just returns another random set of 10 digits:
30 0     0 1 0 sub next_page { shift->{page_number}++; [ map { rand() } 1..10 ] }
  0         0  
  0         0  
31              
32              
33             #==============================================================================
34             sub next
35             {
36 11700     11700 1 77012 my $s = shift;
37            
38 11700 100       31024 if( exists( $s->{data}->[ $s->{idx} ] ) )
39             {
40 11673         39646 return $s->{data}->[ $s->{idx}++ ];
41             }
42             else
43             {
44             # End of the current resultset, see if we can get another page of records:
45 27 100       205 if( my $page = $s->next_page )
46             {
47 26         28680231 $s->{data} = $page;
48 26         10641 $s->{idx} = 0;
49 26         303 return $s->{data}->[ $s->{idx}++ ];
50             }
51             else
52             {
53             # No more pages, no more data:
54 1         10 return;
55             }# end if()
56             }# end if()
57             }# end next()
58              
59              
60             #==============================================================================
61             sub reset
62             {
63 0     0 1 0 my $s = shift;
64            
65 0         0 $s->{idx} = 0;
66             }# end next()
67              
68              
69             #==============================================================================
70 11699     11699 1 56011 sub page_number { shift->{page_number} }
71              
72              
73             1;# return true:
74              
75             =pod
76              
77             =head1 NAME
78              
79             Iterator::Paged - Simple iterator with events for accessing more records.
80              
81             =head1 SYNOPSIS
82              
83             use Iterator::Paged;
84            
85             my $iter = Iterator::Paged->new();
86             while( my $item = $iter->next )
87             {
88             warn $iter->page_number . ": $item\n";
89             last if $iter->page_number > 100;
90             }# end while()
91              
92             Or, more likely, in a subclass:
93              
94             package My::Iterator;
95            
96             use strict;
97             use warnings 'all';
98             use base 'Iterator::Paged';
99            
100             sub next_page
101             {
102             my ($s) = @_;
103            
104             # Return an arrayref of the next "page" of data:
105             return if $s->{page_number}++ >= 4;
106             return [ $s->{idx}.. $s->{idx} + 5 ];
107             }# end get_page()
108              
109             Then, using that class:
110              
111             use My::Iterator;
112            
113             my $iter = My::Iterator->new();
114            
115             while( my $item = $iter->next )
116             {
117             warn "Page " . $iter->page_number . ": $item\n";
118             }# end while()
119              
120             That last example will print the following:
121              
122             Page 1: 0
123             Page 1: 1
124             Page 1: 2
125             Page 1: 3
126             Page 1: 4
127             Page 1: 5
128             Page 2: 6
129             Page 2: 7
130             Page 2: 8
131             Page 2: 9
132             Page 2: 10
133             Page 2: 11
134             Page 3: 12
135             Page 3: 13
136             Page 3: 14
137             Page 3: 15
138             Page 3: 16
139             Page 3: 17
140             Page 4: 18
141             Page 4: 19
142             Page 4: 20
143             Page 4: 21
144             Page 4: 22
145             Page 4: 23
146              
147             =head1 DESCRIPTION
148              
149             Iterator::Paged provides a simple (subclassable) iterator that will attempt to
150             fetch the next "page" of results when the current set is exhausted.
151              
152             For example, suppose you have an iterator for results on Google.com that fetches
153             the first page of results and upon the next call to C fetches the second page,
154             then third page, fourth and so on.
155              
156             =head1 PUBLIC PROPERTIES
157              
158             =head2 next
159              
160             Returns the next record.
161              
162             =head2 page_number
163              
164             Gets the current page number the iterator is on.
165              
166             =head1 PUBLIC METHODS
167              
168             =head2 reset
169              
170             Sets the page number and internal index to C<0>.
171              
172             =head1 ABSTRACT METHODS
173              
174             The following methods should be implemented by subclasses of Iterator::Paged.
175              
176             =head2 next_page( )
177              
178             This method should somehow fetch the next "page" of records and upon success,
179             return an arrayref of records.
180              
181             If no more records are available, the method should return C like so:
182              
183             # No records found:
184             return;
185              
186             =head1 PROTECTED METHODS
187              
188             The following methods I be implemented by subclasses of Iterator::Paged.
189              
190             =head2 _init( )
191              
192             If your iterator class should be initialized after C and before C,
193             use C<_init> for that purpose.
194              
195             =head1 AUTHOR
196              
197             John Drago
198              
199             =head1 COPYRIGHT
200              
201             Copyright 2009 John Drago all rights reserved.
202              
203             =head1 LICENSE
204              
205             This software is free software and may be used and redistributed under the same
206             terms as Perl itself.
207              
208             =cut
209