| 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 | Iterator::BEGIN@22 |
| 26 | 4 | 3 | 407µs | 4.64ms | Iterator::value (recurses: max depth 1, inclusive time 1.52ms) |
| 8 | 1 | 1 | 153µs | 1.39ms | Iterator::_initialize |
| 8 | 4 | 2 | 71µs | 71µs | Iterator::DESTROY (recurses: max depth 1, inclusive time 19µs) |
| 8 | 2 | 1 | 58µs | 1.45ms | Iterator::new |
| 8 | 2 | 1 | 48µs | 3.83ms | Iterator::is_done |
| 15 | 4 | 1 | 37µs | 37µs | Iterator::isnt_exhausted |
| 17 | 1 | 1 | 32µs | 32µs | Iterator::is_exhausted |
| 1 | 1 | 1 | 10µs | 19µs | Iterator::Util::BEGIN@15 |
| 1 | 1 | 1 | 7µs | 10µs | Iterator::Util::BEGIN@16 |
| 1 | 1 | 1 | 3µs | 3µs | Iterator::BEGIN@69 |
| 0 | 0 | 0 | 0s | 0s | Iterator::X::Internal_Error::location |
| 0 | 0 | 0 | 0s | 0s | Iterator::X::full_message |
| 0 | 0 | 0 | 0s | 0s | Iterator::X::location |
| 0 | 0 | 0 | 0s | 0s | Iterator::__ANON__[:78] |
| 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__ |