Filename | /home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator.pm |
Statements | Executed 427 statements in 1.48ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 794µs | 6.91ms | BEGIN@22 | Iterator::
26 | 4 | 3 | 407µs | 4.64ms | value (recurses: max depth 1, inclusive time 1.52ms) | Iterator::
8 | 1 | 1 | 153µs | 1.39ms | _initialize | Iterator::
8 | 4 | 2 | 71µs | 71µs | DESTROY (recurses: max depth 1, inclusive time 19µs) | Iterator::
8 | 2 | 1 | 58µs | 1.45ms | new | Iterator::
8 | 2 | 1 | 48µs | 3.83ms | is_done | Iterator::
15 | 4 | 1 | 37µs | 37µs | isnt_exhausted | Iterator::
17 | 1 | 1 | 32µs | 32µs | is_exhausted | Iterator::
1 | 1 | 1 | 10µs | 19µs | BEGIN@15 | Iterator::Util::
1 | 1 | 1 | 7µs | 10µs | BEGIN@16 | Iterator::Util::
1 | 1 | 1 | 3µs | 3µs | BEGIN@69 | Iterator::
0 | 0 | 0 | 0s | 0s | location | Iterator::X::Internal_Error::
0 | 0 | 0 | 0s | 0s | full_message | Iterator::X::
0 | 0 | 0 | 0s | 0s | location | Iterator::X::
0 | 0 | 0 | 0s | 0s | __ANON__[:78] | Iterator::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | =for gpg | ||||
2 | -----BEGIN PGP SIGNED MESSAGE----- | ||||
3 | Hash: SHA1 | ||||
4 | |||||
5 | =head1 NAME | ||||
6 | |||||
7 | Iterator - A general-purpose iterator class. | ||||
8 | |||||
9 | =head1 VERSION | ||||
10 | |||||
11 | This documentation describes version 0.03 of Iterator.pm, October 10, 2005. | ||||
12 | |||||
13 | =cut | ||||
14 | |||||
15 | 2 | 18µs | 2 | 29µs | # spent 19µs (10+9) within Iterator::Util::BEGIN@15 which was called:
# once (10µs+9µs) by Iterator::Util::BEGIN@28 at line 15 # spent 19µs making 1 call to Iterator::Util::BEGIN@15
# spent 9µs making 1 call to strict::import |
16 | 2 | 70µs | 2 | 13µs | # spent 10µs (7+3) within Iterator::Util::BEGIN@16 which was called:
# once (7µs+3µs) by Iterator::Util::BEGIN@28 at line 16 # spent 10µs making 1 call to Iterator::Util::BEGIN@16
# spent 3µs making 1 call to warnings::import |
17 | package Iterator; | ||||
18 | 1 | 500ns | our $VERSION = '0.03'; | ||
19 | |||||
20 | # Declare exception classes | ||||
21 | use Exception::Class | ||||
22 | # spent 6.91ms (794µs+6.12) within Iterator::BEGIN@22 which was called:
# once (794µs+6.12ms) by Iterator::Util::BEGIN@28 at line 65 | ||||
23 | 1 | 12µs | 1 | 1.28ms | 'Iterator::X' => # spent 1.28ms making 1 call to Exception::Class::import |
24 | { | ||||
25 | description => 'Generic Iterator exception', | ||||
26 | }, | ||||
27 | 'Iterator::X::Parameter_Error' => | ||||
28 | { | ||||
29 | isa => 'Iterator::X', | ||||
30 | description => 'Iterator method parameter error', | ||||
31 | }, | ||||
32 | 'Iterator::X::OptionError' => | ||||
33 | { | ||||
34 | isa => 'Iterator::X', | ||||
35 | fields => 'name', | ||||
36 | description => 'A bad option was passed to an iterator method or function', | ||||
37 | }, | ||||
38 | 'Iterator::X::Exhausted' => | ||||
39 | { | ||||
40 | isa => 'Iterator::X', | ||||
41 | description => 'Attempt to next_value () on an exhausted iterator', | ||||
42 | }, | ||||
43 | 'Iterator::X::Am_Now_Exhausted' => | ||||
44 | { | ||||
45 | isa => 'Iterator::X', | ||||
46 | description => 'Signals Iterator object that it is now exhausted', | ||||
47 | }, | ||||
48 | 'Iterator::X::User_Code_Error' => | ||||
49 | { | ||||
50 | isa => 'Iterator::X', | ||||
51 | fields => 'eval_error', | ||||
52 | description => q{An exception was thrown within the user's code}, | ||||
53 | }, | ||||
54 | 'Iterator::X::IO_Error' => | ||||
55 | { | ||||
56 | isa => 'Iterator::X', | ||||
57 | fields => 'os_error', | ||||
58 | description => q{An I/O error occurred}, | ||||
59 | }, | ||||
60 | 'Iterator::X::Internal_Error' => | ||||
61 | { | ||||
62 | isa => 'Iterator::X', | ||||
63 | description => 'An Iterator.pm internal error. Please contact author.', | ||||
64 | }, | ||||
65 | 1 | 106µs | 1 | 6.91ms | ); # spent 6.91ms making 1 call to Iterator::BEGIN@22 |
66 | |||||
67 | # Class method to help caller catch exceptions | ||||
68 | BEGIN | ||||
69 | # spent 3µs within Iterator::BEGIN@69 which was called:
# once (3µs+0s) by Iterator::Util::BEGIN@28 at line 80 | ||||
70 | # Dave Rolsky added this subroutine in v1.22 of Exception::Class. | ||||
71 | # Thanks, Dave! | ||||
72 | # We define it here so we have the functionality in pre-1.22 versions; | ||||
73 | # we make it conditional so as to avoid a warning in post-1.22 versions. | ||||
74 | *Exception::Class::Base::caught = sub | ||||
75 | { | ||||
76 | my $class = shift; | ||||
77 | return Exception::Class->caught($class); | ||||
78 | } | ||||
79 | 1 | 4µs | if $Exception::Class::VERSION lt '1.22'; | ||
80 | 1 | 458µs | 1 | 3µs | } # spent 3µs making 1 call to Iterator::BEGIN@69 |
81 | |||||
82 | # Croak-like location of error | ||||
83 | sub Iterator::X::location | ||||
84 | { | ||||
85 | my ($pkg,$file,$line); | ||||
86 | my $caller_level = 0; | ||||
87 | while (1) | ||||
88 | { | ||||
89 | ($pkg,$file,$line) = caller($caller_level++); | ||||
90 | last if $pkg !~ /\A Iterator/x && $pkg !~ /\A Exception::Class/x | ||||
91 | } | ||||
92 | return "at $file line $line"; | ||||
93 | } | ||||
94 | |||||
95 | # Die-like location of error | ||||
96 | sub Iterator::X::Internal_Error::location | ||||
97 | { | ||||
98 | my $self = shift; | ||||
99 | return "at " . $self->file () . " line " . $self->line () | ||||
100 | } | ||||
101 | |||||
102 | # Override full_message, to report location of error in caller's code. | ||||
103 | sub Iterator::X::full_message | ||||
104 | { | ||||
105 | my $self = shift; | ||||
106 | |||||
107 | my $msg = $self->message; | ||||
108 | return $msg if substr($msg,-1,1) eq "\n"; | ||||
109 | |||||
110 | $msg =~ s/[ \t]+\z//; # remove any trailing spaces (is this necessary?) | ||||
111 | return $msg . q{ } . $self->location () . qq{\n}; | ||||
112 | } | ||||
113 | |||||
114 | |||||
115 | ## Constructor | ||||
116 | |||||
117 | # Method name: new | ||||
118 | # Synopsis: $iterator = Iterator->new( $code_ref ); | ||||
119 | # Description: Object constructor. | ||||
120 | # Created: 07/27/2005 by EJR | ||||
121 | # Parameters: $code_ref - the iterator sequence generation code. | ||||
122 | # Returns: New Iterator. | ||||
123 | # Exceptions: Iterator::X::Parameter_Error (via _initialize) | ||||
124 | sub new | ||||
125 | # spent 1.45ms (58µs+1.39) within Iterator::new which was called 8 times, avg 181µs/call:
# 4 times (21µs+1.26ms) by Iterator::Util::imap at line 52 of Iterator/Util.pm, avg 320µs/call
# 4 times (37µs+128µs) by Iterator::Util::iarray at line 158 of Iterator/Util.pm, avg 41µs/call | ||||
126 | 8 | 3µs | my $class = shift; | ||
127 | 8 | 4µs | my $self = \do {my $anonymous}; | ||
128 | 8 | 12µs | bless $self, $class; | ||
129 | 8 | 14µs | 8 | 1.39ms | $self->_initialize(@_); # spent 1.39ms making 8 calls to Iterator::_initialize, avg 174µs/call |
130 | 8 | 25µs | return $self; | ||
131 | } | ||||
132 | |||||
133 | { # encapsulation enclosure | ||||
134 | |||||
135 | # Attributes: | ||||
136 | 2 | 400ns | my %code_for; # The sequence code (coderef) for each object. | ||
137 | 1 | 100ns | my %is_exhausted; # Boolean: is this object exhausted? | ||
138 | 1 | 400ns | my %next_value_for; # One-item lookahead buffer for each object. | ||
139 | # [if you update this list of attributes, be sure to edit DESTROY] | ||||
140 | |||||
141 | # Method name: _initialize | ||||
142 | # Synopsis: $iterator->_initialize( $code_ref ); | ||||
143 | # Description: Object initializer. | ||||
144 | # Created: 07/27/2005 by EJR | ||||
145 | # Parameters: $code_ref - the iterator sequence generation code. | ||||
146 | # Returns: Nothing. | ||||
147 | # Exceptions: Iterator::X::Parameter_Error | ||||
148 | # Iterator::X::User_Code_Error | ||||
149 | # Notes: For internal module use only. | ||||
150 | # Caches the first value of the iterator in %next_value_for. | ||||
151 | sub _initialize | ||||
152 | # spent 1.39ms (153µs+1.23) within Iterator::_initialize which was called 8 times, avg 174µs/call:
# 8 times (153µs+1.23ms) by Iterator::new at line 129, avg 174µs/call | ||||
153 | 8 | 2µs | my $self = shift; | ||
154 | |||||
155 | 8 | 3µs | Iterator::X::Parameter_Error->throw(q{Too few parameters to Iterator->new()}) | ||
156 | if @_ < 1; | ||||
157 | 8 | 2µs | Iterator::X::Parameter_Error->throw(q{Too many parameters to Iterator->new()}) | ||
158 | if @_ > 1; | ||||
159 | 8 | 2µs | my $code = shift; | ||
160 | 8 | 4µs | Iterator::X::Parameter_Error->throw (q{Parameter to Iterator->new() must be code reference}) | ||
161 | if ref $code ne 'CODE'; | ||||
162 | |||||
163 | 8 | 10µs | $code_for {$self} = $code; | ||
164 | |||||
165 | # Get the next (first) value for this iterator | ||||
166 | eval | ||||
167 | 8 | 25µs | { | ||
168 | 8 | 22µs | 8 | 1.18ms | $next_value_for{$self} = $code-> (); # spent 1.17ms making 4 calls to Iterator::Util::__ANON__[Iterator/Util.pm:52], avg 293µs/call
# spent 10µs making 4 calls to Iterator::Util::__ANON__[Iterator/Util.pm:158], avg 2µs/call |
169 | }; | ||||
170 | |||||
171 | 8 | 1µs | my $ex; | ||
172 | 8 | 45µs | 8 | 52µs | if ($ex = Iterator::X::Am_Now_Exhausted->caught ()) # spent 52µs making 8 calls to Exception::Class::Base::caught, avg 7µs/call |
173 | { | ||||
174 | # Starting off exhausted is okay | ||||
175 | $is_exhausted{$self} = 1; | ||||
176 | } | ||||
177 | elsif ($@) | ||||
178 | { | ||||
179 | Iterator::X::User_Code_Error->throw (message => "$@", | ||||
180 | eval_error => $@); | ||||
181 | } | ||||
182 | |||||
183 | 8 | 23µs | return; | ||
184 | } | ||||
185 | |||||
186 | # Method name: DESTROY | ||||
187 | # Synopsis: (none) | ||||
188 | # Description: Object destructor. | ||||
189 | # Created: 07/27/2005 by EJR | ||||
190 | # Parameters: None. | ||||
191 | # Returns: Nothing. | ||||
192 | # Exceptions: None. | ||||
193 | # Notes: Invoked automatically by perl. | ||||
194 | # Releases the hash entries used by the object. | ||||
195 | # Module would leak memory otherwise. | ||||
196 | sub DESTROY | ||||
197 | # spent 71µs within Iterator::DESTROY which was called 8 times, avg 9µs/call:
# 3 times (19µs+-19µs) by Iterator::DESTROY at line 199, avg 0s/call
# 2 times (28µs+12µs) by Benchmark::Perl::Formance::find_interesting_result_paths at line 710 of lib/Benchmark/Perl/Formance.pm, avg 20µs/call
# 2 times (12µs+0s) by Benchmark::Perl::Formance::find_interesting_result_paths at line 700 of lib/Benchmark/Perl/Formance.pm, avg 6µs/call
# once (12µs+8µs) by Benchmark::Perl::Formance::find_interesting_result_paths at line 719 of lib/Benchmark/Perl/Formance.pm | ||||
198 | 8 | 2µs | my $self = shift; | ||
199 | 8 | 36µs | 3 | 0s | delete $code_for{$self}; # spent 19µs making 3 calls to Iterator::DESTROY, avg 6µs/call, recursion: max depth 1, sum of overlapping time 19µs |
200 | 8 | 5µs | delete $is_exhausted{$self}; | ||
201 | 8 | 39µs | delete $next_value_for{$self}; | ||
202 | } | ||||
203 | |||||
204 | # Method name: value | ||||
205 | # Synopsis: $next_value = $iterator->value(); | ||||
206 | # Description: Returns each value of the sequence in turn. | ||||
207 | # Created: 07/27/2005 by EJR | ||||
208 | # Parameters: None. | ||||
209 | # Returns: Next value, as generated by caller's code ref. | ||||
210 | # Exceptions: Iterator::X::Exhausted | ||||
211 | # Notes: Keeps one forward-looking value for the iterator in | ||||
212 | # %next_value_for. This is so we have something to | ||||
213 | # return when user's code throws Am_Now_Exhausted. | ||||
214 | sub value | ||||
215 | # spent 4.64ms (407µs+4.24) within Iterator::value which was called 26 times, avg 179µs/call:
# 13 times (188µs+883µs) by Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:52] at line 50 of Iterator/Util.pm, avg 82µs/call
# 10 times (150µs+2.01ms) by Benchmark::Perl::Formance::find_interesting_result_paths at line 706 of lib/Benchmark/Perl/Formance.pm, avg 216µs/call
# 2 times (52µs+916µs) by Benchmark::Perl::Formance::find_interesting_result_paths at line 702 of lib/Benchmark/Perl/Formance.pm, avg 484µs/call
# once (17µs+424µs) by Data::DPath::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Data/DPath.pm:47] at line 41 of Data/DPath.pm | ||||
216 | 26 | 7µs | my $self = shift; | ||
217 | |||||
218 | 26 | 16µs | Iterator::X::Exhausted->throw(q{Iterator is exhausted}) | ||
219 | if $is_exhausted{$self}; | ||||
220 | |||||
221 | # The value that we'll be returning this time. | ||||
222 | 26 | 14µs | my $this_value = $next_value_for{$self}; | ||
223 | |||||
224 | # Compute the value that we'll return next time | ||||
225 | eval | ||||
226 | 26 | 60µs | { | ||
227 | 26 | 63µs | 26 | 5.58ms | $next_value_for{$self} = $code_for{$self}->(@_); # spent 3.26ms making 13 calls to Iterator::Util::__ANON__[Iterator/Util.pm:52], avg 251µs/call
# spent 2.31ms making 13 calls to Iterator::Util::__ANON__[Iterator/Util.pm:158], avg 178µs/call |
228 | }; | ||||
229 | 26 | 117µs | 34 | 184µs | if (my $ex = Iterator::X::Am_Now_Exhausted->caught ()) # spent 173µs making 26 calls to Exception::Class::Base::caught, avg 7µs/call
# spent 11µs making 8 calls to Exception::Class::Base::__ANON__[Exception/Class/Base.pm:35], avg 1µs/call |
230 | { | ||||
231 | # Aha, we're done; we'll have to stop next time. | ||||
232 | $is_exhausted{$self} = 1; | ||||
233 | } | ||||
234 | elsif ($@) | ||||
235 | { | ||||
236 | Iterator::X::User_Code_Error->throw (message => "$@", | ||||
237 | eval_error => $@); | ||||
238 | } | ||||
239 | |||||
240 | 26 | 84µs | return $this_value; | ||
241 | } | ||||
242 | |||||
243 | # Method name: is_exhausted | ||||
244 | # Synopsis: $boolean = $iterator->is_exhausted(); | ||||
245 | # Description: Flag indicating that the iterator is exhausted. | ||||
246 | # Created: 07/27/2005 by EJR | ||||
247 | # Parameters: None. | ||||
248 | # Returns: Current value of %is_exhausted for this object. | ||||
249 | # Exceptions: None. | ||||
250 | sub is_exhausted | ||||
251 | # spent 32µs within Iterator::is_exhausted which was called 17 times, avg 2µs/call:
# 17 times (32µs+0s) by Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:52] at line 48 of Iterator/Util.pm, avg 2µs/call | ||||
252 | 17 | 5µs | my $self = shift; | ||
253 | |||||
254 | 17 | 64µs | return $is_exhausted{$self}; | ||
255 | } | ||||
256 | |||||
257 | # Method name: isnt_exhausted | ||||
258 | # Synopsis: $boolean = $iterator->isnt_exhausted(); | ||||
259 | # Description: Flag indicating that the iterator is NOT exhausted. | ||||
260 | # Created: 07/27/2005 by EJR | ||||
261 | # Parameters: None. | ||||
262 | # Returns: Logical NOT of %is_exhausted for this object. | ||||
263 | # Exceptions: None. | ||||
264 | sub isnt_exhausted | ||||
265 | # spent 37µs within Iterator::isnt_exhausted which was called 15 times, avg 2µs/call:
# 10 times (23µs+0s) by Benchmark::Perl::Formance::find_interesting_result_paths at line 707 of lib/Benchmark/Perl/Formance.pm, avg 2µs/call
# 2 times (5µs+0s) by Benchmark::Perl::Formance::find_interesting_result_paths at line 705 of lib/Benchmark/Perl/Formance.pm, avg 3µs/call
# 2 times (5µs+0s) by Benchmark::Perl::Formance::find_interesting_result_paths at line 710 of lib/Benchmark/Perl/Formance.pm, avg 2µs/call
# once (4µs+0s) by Benchmark::Perl::Formance::find_interesting_result_paths at line 700 of lib/Benchmark/Perl/Formance.pm | ||||
266 | 15 | 4µs | my $self = shift; | ||
267 | |||||
268 | 15 | 62µs | return ! $is_exhausted{$self}; | ||
269 | } | ||||
270 | |||||
271 | } # end of encapsulation enclosure | ||||
272 | |||||
273 | |||||
274 | # Function name: is_done | ||||
275 | # Synopsis: Iterator::is_done (); | ||||
276 | # Description: Convenience function. Throws an Am_Now_Exhausted exception. | ||||
277 | # Created: 08/02/2005 by EJR, per Will Coleda's suggestion. | ||||
278 | # Parameters: None. | ||||
279 | # Returns: Doesn't return. | ||||
280 | # Exceptions: Iterator::X::Am_Now_Exhausted | ||||
281 | sub is_done | ||||
282 | # spent 3.83ms (48µs+3.78) within Iterator::is_done which was called 8 times, avg 478µs/call:
# 4 times (28µs+2.26ms) by Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:158] at line 156 of Iterator/Util.pm, avg 571µs/call
# 4 times (20µs+1.52ms) by Iterator::Util::__ANON__[/home/ss5/perl5/perlbrew/perls/tapper-perl/lib/site_perl/5.16.3/Iterator/Util.pm:52] at line 48 of Iterator/Util.pm, avg 386µs/call | ||||
283 | 8 | 33µs | 8 | 3.78ms | Iterator::X::Am_Now_Exhausted->throw() # spent 3.78ms making 8 calls to Exception::Class::Base::throw, avg 472µs/call |
284 | } | ||||
285 | |||||
286 | |||||
287 | 1 | 3µs | 1; | ||
288 | __END__ |