File Coverage

blib/lib/Class/Iterator.pm
Criterion Covered Total %
statement 44 59 74.5
branch 8 12 66.6
condition 4 5 80.0
subroutine 13 15 86.6
pod 4 7 57.1
total 73 98 74.4


line stmt bran cond sub pod time code
1             package Class::Iterator;
2              
3              
4             # Copyright (c) 2003 Robert Silve
5             # All rights reserved.
6             # This program is free software; you can redistribute it and/or modify it
7             # under the same terms as Perl itself.
8              
9              
10             require Exporter;
11             our @ISA = qw(Exporter);
12             our @EXPORT = qw(imap igrep);
13              
14 2     2   50568 use Carp;
  2         6  
  2         1698  
15              
16             our $VERSION = "0.3";
17              
18             sub new {
19 8     8 1 73 my $proto = shift;
20 8   66     42 my $class = ref($proto) || $proto;
21 8         16 my $self = {};
22 8         21 bless ($self, $class);
23 8   100 1   43 $self->generator(shift || sub { return sub { return } });
  1         7  
  1         5  
24 8         24 $self->init;
25 8         27 return $self;
26             }
27              
28             sub init {
29 9     9 0 17 my $self = shift;
30 9         19 $self->iterator($self->generator->())
31             }
32              
33              
34             sub next {
35 309     309 1 120021 my $self = shift;
36 309         665 return $self->iterator->();
37             }
38              
39             sub generator {
40 18     18 0 27 my $self = shift;
41 18         23 my $arg = shift;
42 18 100       41 if ($arg) {
43 8         37 $self->{_generator} = $arg;
44             } else {
45 10         37 return $self->{_generator};
46             }
47              
48             }
49              
50             sub iterator {
51 321     321 0 404 my $self = shift;
52 321         325 my $arg = shift;
53 321 100       587 if ($arg) {
54 9         23 $self->{_iterator} = $arg;
55             } else {
56 312         940 return $self->{_iterator};
57             }
58              
59             }
60              
61             sub AUTOLOAD {
62 0     0   0 my ($self) = @_;
63 0         0 my ($pack, $meth) =($AUTOLOAD =~ /^(.*)::(.*)$/);
64 0         0 my @auth = qw(generator iterator);
65 0         0 my %auth = map { $_ => 1 } @auth;
  0         0  
66 0 0       0 unless ($auth{$meth}) {
67 0         0 croak "Unknow method $meth";
68             }
69            
70             my $code = sub {
71 0     0   0 my $self = shift;
72 0         0 my $arg = shift;
73 0 0       0 if ($arg) {
74 0         0 $self->{"_$meth"} = $arg;
75             } else {
76 0         0 return $self->{"_$meth"};
77             }
78 0         0 };
79            
80 0         0 *$AUTOLOAD = $code;
81 0         0 goto &$AUTOLOAD;
82            
83             }
84              
85             sub _imap {
86 1     1   96 my ($rule, $generator) = @_;
87 1         5 my $it = $generator->();
88             return sub {
89             return sub {
90 101         317 local $_ = $it->();
91 101 100       481 return unless defined $_;
92 100         209 return $rule->();
93             }
94 1     1   7 }
95            
96 1         13 }
97              
98             sub imap (&$) {
99 1     1 1 369 my ($rule, $self) = @_;
100 1         3 return $self->new(_imap($rule, $self->generator));
101             }
102              
103              
104             sub _igrep {
105 3     3   7 my ($rule, $it) = @_;
106             # my $it = $generator->();
107             return sub {
108             return sub {
109 12         36 while ( defined(my $v = $it->()) ) {
110 116         759 local $_ = $v;
111 116 100       195 return $_ if $rule->();
112             }
113 2         16 return;
114             }
115 3     3   18 }
116            
117 3         20 }
118              
119              
120             sub igrep (&$) {
121 3     3 1 15 my ($rule, $self) = @_;
122 3         9 return $self->new(_igrep($rule, $self->iterator));
123             }
124              
125              
126              
127             1;
128              
129              
130             __END__
131              
132              
133             # Below is stub documentation for your module. You better edit it!
134              
135             =head1 NAME
136              
137             Class::Iterator - Iterator class
138              
139             =head1 SYNOPSIS
140              
141             use Class::Iterator;
142             my $it = Class::Iterator->new(\&closure_generator);
143              
144             while (my $v = $it->next) { print "value : $v\n" }
145            
146             # use map like
147             my $it2 = imap { ...some code with $_...} $it
148             while (my $v = $it->next) { print "value : $v\n" }
149              
150             # use grep like
151             my $it3 = igrep { ...some code with $_...} $it
152             while (my $v = $it->next) { print "value : $v\n" }
153              
154              
155             =head1 DESCRIPTION
156              
157             Class::Iterator is a generic iterator object class. It use a closure an wrap
158             into an object interface.
159              
160             =over 4
161              
162             =item new(\&closure_generator)
163              
164             This is the constructor. The argument is a sub which look like
165             sub closure_generator {
166             my $private_data;
167             return sub {
168             # do something with $private_data
169             # and return it
170             return $private_data
171             }
172             }
173              
174             =item next
175              
176             calling this method make one iteration.
177              
178             =item $o = imap { ... } $it
179              
180             This a creator. It create a new iterator from an existant
181             iterator in the manner of map.
182              
183             =item $o = igrep { ... } $it
184              
185             This a creator. It create a new iterator from an existant
186             iterator in the manner of grep.
187              
188              
189             =back
190              
191             =head1 CREDITS
192              
193             Marc Jason Dominius's YAPC::EU 2003 classes.
194             Ken Olstad
195              
196             =head1 AUTHOR
197              
198             Robert Silve <robert@silve.net>
199              
200             =cut