Profile of Iterator.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For bin/dpath
Run on Tue Jun 5 15:31:33 2012
Reported on Tue Jun 5 15:31:43 2012

Filename | /home/ss5/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Iterator.pm
Statements | Executed 13 statements in 4.12ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 5.82ms | 43.0ms | Iterator::::BEGIN@22 Iterator::BEGIN@22
1 | 1 | 1 | 54µs | 69µs | Iterator::Util::::BEGIN@15 Iterator::Util::BEGIN@15
1 | 1 | 1 | 29µs | 58µs | Iterator::Util::::BEGIN@16 Iterator::Util::BEGIN@16
1 | 1 | 1 | 17µs | 17µs | Iterator::::BEGIN@69 Iterator::BEGIN@69
0 | 0 | 0 | 0s | 0s | Iterator::::DESTROY Iterator::DESTROY
0 | 0 | 0 | 0s | 0s | Iterator::X::Internal_Error::::locationIterator::X::Internal_Error::location
0 | 0 | 0 | 0s | 0s | Iterator::X::::full_message Iterator::X::full_message
0 | 0 | 0 | 0s | 0s | Iterator::X::::location Iterator::X::location
0 | 0 | 0 | 0s | 0s | Iterator::::__ANON__[:78] Iterator::__ANON__[:78]
0 | 0 | 0 | 0s | 0s | Iterator::::_initialize Iterator::_initialize
0 | 0 | 0 | 0s | 0s | Iterator::::is_done Iterator::is_done
0 | 0 | 0 | 0s | 0s | Iterator::::is_exhausted Iterator::is_exhausted
0 | 0 | 0 | 0s | 0s | Iterator::::isnt_exhausted Iterator::isnt_exhausted
0 | 0 | 0 | 0s | 0s | Iterator::::new Iterator::new
0 | 0 | 0 | 0s | 0s | Iterator::::value Iterator::value

Call graph for these subroutines as a Graphviz dot language file.

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 | 94µs | 2 | 84µs | # spent 69µs (54+15) within Iterator::Util::BEGIN@15 which was called: # once (54µs+15µs) by Iterator::Util::BEGIN@28 at line 15 use strict; # spent 69µs making 1 call to Iterator::Util::BEGIN@15 # spent 15µs making 1 call to strict::import
16 | 2 | 505µs | 2 | 88µs | # spent 58µs (29+29) within Iterator::Util::BEGIN@16 which was called: # once (29µs+29µs) by Iterator::Util::BEGIN@28 at line 16 use warnings; # spent 58µs making 1 call to Iterator::Util::BEGIN@16 # spent 29µs making 1 call to warnings::import
17 |  |  |  |  | package Iterator;
18 | 1 | 3µs |  |  | our $VERSION = '0.03';
19 |  |  |  |  |
20 |  |  |  |  | # Declare exception classes
21 |  |  |  |  | use Exception::Class
22 |  |  |  |  | # spent 43.0ms (5.82+37.1) within Iterator::BEGIN@22 which was called: # once (5.82ms+37.1ms) by Iterator::Util::BEGIN@28 at line 65 (
23 |  |  | 1 | 7.40ms | 'Iterator::X' => # spent 7.40ms 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 | 2 | 715µs | 1 | 43.0ms | ); # spent 43.0ms making 1 call to Iterator::BEGIN@22
66 |  |  |  |  |
67 |  |  |  |  | # Class method to help caller catch exceptions
68 |  |  |  |  | BEGIN
69 |  |  |  |  | # spent 17µs within Iterator::BEGIN@69 which was called: # once (17µ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 | 18µs |  |  | if $Exception::Class::VERSION lt '1.22';
80 | 1 | 2.76ms | 1 | 17µs | } # spent 17µ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 |  |  |  |  | {
126 |  |  |  |  | my $class = shift;
127 |  |  |  |  | my $self = \do {my $anonymous};
128 |  |  |  |  | bless $self, $class;
129 |  |  |  |  | $self->_initialize(@_);
130 |  |  |  |  | return $self;
131 |  |  |  |  | }
132 |  |  |  |  |
133 |  |  |  |  | { # encapsulation enclosure
134 |  |  |  |  |
135 |  |  |  |  | # Attributes:
136 | 4 | 6µs |  |  | my %code_for; # The sequence code (coderef) for each object.
137 |  |  |  |  | my %is_exhausted; # Boolean: is this object exhausted?
138 |  |  |  |  | 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 |  |  |  |  | {
153 |  |  |  |  | my $self = shift;
154 |  |  |  |  |
155 |  |  |  |  | Iterator::X::Parameter_Error->throw(q{Too few parameters to Iterator->new()})
156 |  |  |  |  | if @_ < 1;
157 |  |  |  |  | Iterator::X::Parameter_Error->throw(q{Too many parameters to Iterator->new()})
158 |  |  |  |  | if @_ > 1;
159 |  |  |  |  | my $code = shift;
160 |  |  |  |  | Iterator::X::Parameter_Error->throw (q{Parameter to Iterator->new() must be code reference})
161 |  |  |  |  | if ref $code ne 'CODE';
162 |  |  |  |  |
163 |  |  |  |  | $code_for {$self} = $code;
164 |  |  |  |  |
165 |  |  |  |  | # Get the next (first) value for this iterator
166 |  |  |  |  | eval
167 |  |  |  |  | {
168 |  |  |  |  | $next_value_for{$self} = $code-> ();
169 |  |  |  |  | };
170 |  |  |  |  |
171 |  |  |  |  | my $ex;
172 |  |  |  |  | if ($ex = Iterator::X::Am_Now_Exhausted->caught ())
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 |  |  |  |  | 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 |  |  |  |  | {
198 |  |  |  |  | my $self = shift;
199 |  |  |  |  | delete $code_for{$self};
200 |  |  |  |  | delete $is_exhausted{$self};
201 |  |  |  |  | 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 |  |  |  |  | {
216 |  |  |  |  | my $self = shift;
217 |  |  |  |  |
218 |  |  |  |  | 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 |  |  |  |  | my $this_value = $next_value_for{$self};
223 |  |  |  |  |
224 |  |  |  |  | # Compute the value that we'll return next time
225 |  |  |  |  | eval
226 |  |  |  |  | {
227 |  |  |  |  | $next_value_for{$self} = $code_for{$self}->(@_);
228 |  |  |  |  | };
229 |  |  |  |  | if (my $ex = Iterator::X::Am_Now_Exhausted->caught ())
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 |  |  |  |  | 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 |  |  |  |  | {
252 |  |  |  |  | my $self = shift;
253 |  |  |  |  |
254 |  |  |  |  | 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 |  |  |  |  | {
266 |  |  |  |  | my $self = shift;
267 |  |  |  |  |
268 |  |  |  |  | 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 |  |  |  |  | {
283 |  |  |  |  | Iterator::X::Am_Now_Exhausted->throw()
284 |  |  |  |  | }
285 |  |  |  |  |
286 |  |  |  |  |
287 | 1 | 18µs |  |  | 1;
288 |  |  |  |  | __END__