| Filename | /usr/share/perl5/DateTime/Format/Builder/Parser.pm |
| Statements | Executed 563 statements in 5.56ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 622µs | 799µs | DateTime::Format::Builder::Parser::BEGIN@626 |
| 10 | 2 | 1 | 569µs | 3.33ms | DateTime::Format::Builder::Parser::create_single_parser |
| 3 | 1 | 1 | 194µs | 3.54ms | DateTime::Format::Builder::Parser::sort_parsers |
| 3 | 2 | 1 | 91µs | 3.68ms | DateTime::Format::Builder::Parser::create_multiple_parsers |
| 10 | 1 | 1 | 87µs | 87µs | DateTime::Format::Builder::Parser::params |
| 4 | 4 | 4 | 82µs | 82µs | DateTime::Format::Builder::Parser::valid_params |
| 14 | 2 | 1 | 65µs | 85µs | DateTime::Format::Builder::Parser::__ANON__[:170] |
| 3 | 1 | 1 | 48µs | 3.73ms | DateTime::Format::Builder::Parser::create_parser |
| 10 | 1 | 1 | 46µs | 46µs | DateTime::Format::Builder::Parser::params_all |
| 14 | 2 | 1 | 39µs | 39µs | DateTime::Format::Builder::Parser::__ANON__[:171] |
| 5 | 1 | 1 | 32µs | 32µs | DateTime::Format::Builder::Parser::merge_callbacks |
| 10 | 1 | 1 | 32µs | 32µs | DateTime::Format::Builder::Parser::whose_params |
| 3 | 1 | 1 | 26µs | 26µs | DateTime::Format::Builder::Parser::new |
| 1 | 1 | 1 | 21µs | 79µs | DateTime::Format::Builder::Parser::BEGIN@8 |
| 1 | 1 | 1 | 20µs | 25µs | DateTime::Format::Builder::Parser::BEGIN@2 |
| 14 | 1 | 1 | 20µs | 20µs | DateTime::Format::Builder::Parser::CORE:match (opcode) |
| 7 | 1 | 1 | 14µs | 14µs | DateTime::Format::Builder::Parser::chain_parsers |
| 3 | 1 | 1 | 14µs | 14µs | DateTime::Format::Builder::Parser::set_maker |
| 1 | 1 | 1 | 11µs | 65µs | DateTime::Format::Builder::Parser::BEGIN@5 |
| 1 | 1 | 1 | 11µs | 48µs | DateTime::Format::Builder::Parser::BEGIN@4 |
| 1 | 1 | 1 | 9µs | 36µs | DateTime::Format::Builder::Parser::BEGIN@3 |
| 3 | 1 | 1 | 9µs | 9µs | DateTime::Format::Builder::Parser::set_parser |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::__ANON__[:374] |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::__ANON__[:455] |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::__ANON__[:542] |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::create_single_object |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::fail |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::maker |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::no_parser |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::on_fail |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::parse |
| 0 | 0 | 0 | 0s | 0s | DateTime::Format::Builder::Parser::set_fail |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package DateTime::Format::Builder::Parser; | ||||
| 2 | 3 | 39µs | 2 | 30µs | # spent 25µs (20+5) within DateTime::Format::Builder::Parser::BEGIN@2 which was called:
# once (20µs+5µs) by DateTime::Format::MySQL::BEGIN@11 at line 2 # spent 25µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@2
# spent 5µs making 1 call to strict::import |
| 3 | 3 | 32µs | 2 | 64µs | # spent 36µs (9+27) within DateTime::Format::Builder::Parser::BEGIN@3 which was called:
# once (9µs+27µs) by DateTime::Format::MySQL::BEGIN@11 at line 3 # spent 36µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@3
# spent 28µs making 1 call to vars::import |
| 4 | 3 | 37µs | 2 | 85µs | # spent 48µs (11+37) within DateTime::Format::Builder::Parser::BEGIN@4 which was called:
# once (11µs+37µs) by DateTime::Format::MySQL::BEGIN@11 at line 4 # spent 48µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@4
# spent 37µs making 1 call to Exporter::import |
| 5 | 1 | 54µs | # spent 65µs (11+54) within DateTime::Format::Builder::Parser::BEGIN@5 which was called:
# once (11µs+54µs) by DateTime::Format::MySQL::BEGIN@11 at line 7 # spent 54µs making 1 call to Exporter::import | ||
| 6 | validate SCALAR CODEREF UNDEF ARRAYREF | ||||
| 7 | 3 | 45µs | 1 | 65µs | ); # spent 65µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@5 |
| 8 | 3 | 2.17ms | 2 | 136µs | # spent 79µs (21+57) within DateTime::Format::Builder::Parser::BEGIN@8 which was called:
# once (21µs+57µs) by DateTime::Format::MySQL::BEGIN@11 at line 8 # spent 79µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@8
# spent 57µs making 1 call to Exporter::import |
| 9 | |||||
| 10 | =head1 NAME | ||||
| 11 | |||||
| - - | |||||
| 27 | 1 | 4µs | $VERSION = '0.77'; | ||
| 28 | |||||
| 29 | =head1 CONSTRUCTORS | ||||
| 30 | |||||
| - - | |||||
| 33 | sub on_fail | ||||
| 34 | { | ||||
| 35 | my ($self, $input, $parent) = @_; | ||||
| 36 | my $maker = $self->maker; | ||||
| 37 | if ( $maker and $maker->can( 'on_fail' ) ) { | ||||
| 38 | $maker->on_fail( $input ); | ||||
| 39 | } else { | ||||
| 40 | croak __PACKAGE__.": Invalid date format: $input"; | ||||
| 41 | } | ||||
| 42 | } | ||||
| 43 | |||||
| 44 | sub no_parser | ||||
| 45 | { | ||||
| 46 | croak "No parser set for this parser object."; | ||||
| 47 | } | ||||
| 48 | |||||
| 49 | sub new | ||||
| 50 | # spent 26µs within DateTime::Format::Builder::Parser::new which was called 3 times, avg 9µs/call:
# 3 times (26µs+0s) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 394, avg 9µs/call | ||||
| 51 | 15 | 37µs | my $class = shift; | ||
| 52 | $class = ref($class)||$class; | ||||
| 53 | my $i = 0; | ||||
| 54 | my $self = bless { | ||||
| 55 | on_fail => \&on_fail, | ||||
| 56 | parser => \&no_parser, | ||||
| 57 | }, $class; | ||||
| 58 | |||||
| 59 | return $self; | ||||
| 60 | } | ||||
| 61 | |||||
| 62 | sub maker { $_[0]->{maker} } | ||||
| 63 | |||||
| 64 | sub set_maker | ||||
| 65 | # spent 14µs within DateTime::Format::Builder::Parser::set_maker which was called 3 times, avg 5µs/call:
# 3 times (14µs+0s) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 408, avg 5µs/call | ||||
| 66 | 15 | 17µs | my $self = shift; | ||
| 67 | my $maker = shift; | ||||
| 68 | |||||
| 69 | $self->{maker} = $maker; | ||||
| 70 | weaken $self->{maker} | ||||
| 71 | if ref $self->{maker}; | ||||
| 72 | |||||
| 73 | return $self; | ||||
| 74 | } | ||||
| 75 | |||||
| 76 | sub fail | ||||
| 77 | { | ||||
| 78 | my ($self, $parent, $input) = @_; | ||||
| 79 | $self->{on_fail}->( $self, $input, $parent ); | ||||
| 80 | } | ||||
| 81 | |||||
| 82 | sub parse | ||||
| 83 | { | ||||
| 84 | my ( $self, $parent, $input, @args ) = @_; | ||||
| 85 | my $r = $self->{parser}->( $parent, $input, @args ); | ||||
| 86 | $self->fail( $parent, $input ) unless defined $r; | ||||
| 87 | $r; | ||||
| 88 | } | ||||
| 89 | |||||
| 90 | sub set_parser | ||||
| 91 | # spent 9µs within DateTime::Format::Builder::Parser::set_parser which was called 3 times, avg 3µs/call:
# 3 times (9µs+0s) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 456, avg 3µs/call | ||||
| 92 | 9 | 12µs | my ($self, $parser) = @_; | ||
| 93 | $self->{parser} = $parser; | ||||
| 94 | $self; | ||||
| 95 | } | ||||
| 96 | |||||
| 97 | sub set_fail | ||||
| 98 | { | ||||
| 99 | my ($self, $fail) = @_; | ||||
| 100 | $self->{on_fail} = $fail; | ||||
| 101 | $self; | ||||
| 102 | } | ||||
| 103 | |||||
| 104 | =head1 METHODS | ||||
| 105 | |||||
| - - | |||||
| 121 | 1 | 3µs | my @callbacks = qw( on_match on_fail postprocess preprocess ); | ||
| 122 | |||||
| 123 | { | ||||
| 124 | |||||
| 125 | 1 | 900ns | =head3 Common parameters | ||
| 126 | |||||
| - - | |||||
| 164 | my %params = ( | ||||
| 165 | common => { | ||||
| 166 | length => { | ||||
| 167 | type => SCALAR|ARRAYREF, | ||||
| 168 | optional => 1, | ||||
| 169 | callbacks => { | ||||
| 170 | 14 | 94µs | 14 | 20µs | # spent 85µs (65+20) within DateTime::Format::Builder::Parser::__ANON__[/usr/share/perl5/DateTime/Format/Builder/Parser.pm:170] which was called 14 times, avg 6µs/call:
# 7 times (35µs+11µs) by Params::Validate::_validate at line 311, avg 7µs/call
# 7 times (30µs+9µs) by Params::Validate::_validate at line 333, avg 6µs/call # spent 20µs making 14 calls to DateTime::Format::Builder::Parser::CORE:match, avg 1µs/call |
| 171 | 14 | 67µs | # spent 39µs within DateTime::Format::Builder::Parser::__ANON__[/usr/share/perl5/DateTime/Format/Builder/Parser.pm:171] which was called 14 times, avg 3µs/call:
# 7 times (20µs+0s) by Params::Validate::_validate at line 333, avg 3µs/call
# 7 times (18µs+0s) by Params::Validate::_validate at line 311, avg 3µs/call | ||
| 172 | } | ||||
| 173 | }, | ||||
| 174 | |||||
| 175 | # Stuff used by callbacks | ||||
| 176 | label => { type => SCALAR, optional => 1 }, | ||||
| 177 | 3 | 30µs | ( map { $_ => { type => CODEREF|ARRAYREF, optional => 1 } } @callbacks ), | ||
| 178 | }, | ||||
| 179 | ); | ||||
| 180 | |||||
| 181 | =head3 params | ||||
| 182 | |||||
| - - | |||||
| 191 | sub params | ||||
| 192 | # spent 87µs within DateTime::Format::Builder::Parser::params which was called 10 times, avg 9µs/call:
# 10 times (87µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 333, avg 9µs/call | ||||
| 193 | 30 | 99µs | my $self = shift; | ||
| 194 | my $caller = ref $self || $self; | ||||
| 195 | return { map { %$_ } @params{ $caller, 'common' } } | ||||
| 196 | } | ||||
| 197 | |||||
| 198 | =head3 params_all | ||||
| 199 | |||||
| - - | |||||
| 207 | my $all_params; | ||||
| 208 | sub params_all | ||||
| 209 | # spent 46µs within DateTime::Format::Builder::Parser::params_all which was called 10 times, avg 5µs/call:
# 10 times (46µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 311, avg 5µs/call | ||||
| 210 | 14 | 61µs | return $all_params if defined $all_params; | ||
| 211 | my %all_params = map { %$_ } values %params; | ||||
| 212 | $_->{optional} = 1 for values %all_params; | ||||
| 213 | $all_params = \%all_params; | ||||
| 214 | } | ||||
| 215 | |||||
| 216 | =head3 valid_params | ||||
| 217 | |||||
| - - | |||||
| 226 | my %inverse; | ||||
| 227 | sub valid_params | ||||
| 228 | # spent 82µs within DateTime::Format::Builder::Parser::valid_params which was called 4 times, avg 21µs/call:
# once (22µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.3 at line 71 of DateTime/Format/Builder/Parser/Quick.pm
# once (22µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.4 at line 101 of DateTime/Format/Builder/Parser/Regex.pm
# once (20µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1 at line 84 of DateTime/Format/Builder/Parser/Dispatch.pm
# once (18µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.5 at line 35 of DateTime/Format/Builder/Parser/Strptime.pm | ||||
| 229 | 28 | 84µs | my $self = shift; | ||
| 230 | my $from = (caller)[0]; | ||||
| 231 | my %args = @_; | ||||
| 232 | $params{ $from } = \%args; | ||||
| 233 | for (keys %args) | ||||
| 234 | { | ||||
| 235 | # %inverse contains keys matching all the | ||||
| 236 | # possible params; values are the class if and | ||||
| 237 | # only if that class is the only one that uses | ||||
| 238 | # the given param. | ||||
| 239 | 8 | 22µs | $inverse{$_} = exists $inverse{$_} ? undef : $from; | ||
| 240 | } | ||||
| 241 | undef $all_params; | ||||
| 242 | 1; | ||||
| 243 | } | ||||
| 244 | |||||
| 245 | =head3 whose_params | ||||
| 246 | |||||
| - - | |||||
| 254 | sub whose_params | ||||
| 255 | # spent 32µs within DateTime::Format::Builder::Parser::whose_params which was called 10 times, avg 3µs/call:
# 10 times (32µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 323, avg 3µs/call | ||||
| 256 | 20 | 44µs | my $param = shift; | ||
| 257 | return $inverse{$param}; | ||||
| 258 | } | ||||
| 259 | } | ||||
| 260 | |||||
| 261 | =head2 Organising and Creating Parsers | ||||
| 262 | |||||
| - - | |||||
| 296 | sub create_single_object | ||||
| 297 | { | ||||
| 298 | my ( $self ) = shift; | ||||
| 299 | my $obj = $self->new; | ||||
| 300 | my $parser = $self->create_single_parser( @_ ); | ||||
| 301 | |||||
| 302 | $obj->set_parser( $parser ); | ||||
| 303 | } | ||||
| 304 | |||||
| 305 | sub create_single_parser | ||||
| 306 | # spent 3.33ms (569µs+2.76) within DateTime::Format::Builder::Parser::create_single_parser which was called 10 times, avg 333µs/call:
# 7 times (422µs+2.03ms) by DateTime::Format::Builder::Parser::sort_parsers at line 501, avg 350µs/call
# 3 times (148µs+733µs) by DateTime::Format::Builder::Parser::sort_parsers at line 512, avg 294µs/call | ||||
| 307 | 120 | 803µs | my $class = shift; | ||
| 308 | return $_[0] if ref $_[0] eq 'CODE'; # already code | ||||
| 309 | @_ = %{ $_[0] } if ref $_[0] eq 'HASH'; # turn hashref into hash | ||||
| 310 | # ordinary boring sort | ||||
| 311 | 1 | 454µs | 44 | 957µs | my %args = validate( @_, params_all() ); # spent 817µs making 10 calls to Params::Validate::_validate, avg 82µs/call
# spent 46µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:170], avg 7µs/call
# spent 46µs making 10 calls to DateTime::Format::Builder::Parser::params_all, avg 5µs/call
# spent 31µs making 10 calls to DateTime::Format::Builder::Parser::Regex::__ANON__[DateTime/Format/Builder/Parser/Regex.pm:84], avg 3µs/call
# spent 18µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:171], avg 3µs/call # spent 41µs executing statements in 10 string evals (merged) |
| 312 | |||||
| 313 | # Determine variables for ease of reference. | ||||
| 314 | for (@callbacks) | ||||
| 315 | { | ||||
| 316 | 40 | 54µs | 5 | 32µs | $args{$_} = $class->merge_callbacks( $args{$_} ) if $args{$_}; # spent 32µs making 5 calls to DateTime::Format::Builder::Parser::merge_callbacks, avg 6µs/call |
| 317 | } | ||||
| 318 | |||||
| 319 | # Determine parser class | ||||
| 320 | my $from; | ||||
| 321 | for ( keys %args ) | ||||
| 322 | { | ||||
| 323 | 30 | 38µs | 10 | 32µs | $from = whose_params( $_ ); # spent 32µs making 10 calls to DateTime::Format::Builder::Parser::whose_params, avg 3µs/call |
| 324 | next if (not defined $from) or ($from eq 'common'); | ||||
| 325 | last; | ||||
| 326 | } | ||||
| 327 | croak "Could not identify a parsing module to use." unless $from; | ||||
| 328 | |||||
| 329 | # Find and call parser creation method | ||||
| 330 | 10 | 36µs | my $method = $from->can( "create_parser" ) # spent 36µs making 10 calls to UNIVERSAL::can, avg 4µs/call | ||
| 331 | or croak "Can't create a $_ parser (no appropriate create_parser method)"; | ||||
| 332 | my @args = %args; | ||||
| 333 | 1 | 441µs | 44 | 926µs | %args = validate( @args, $from->params() ); # spent 747µs making 10 calls to Params::Validate::_validate, avg 75µs/call
# spent 87µs making 10 calls to DateTime::Format::Builder::Parser::params, avg 9µs/call
# spent 39µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:170], avg 6µs/call
# spent 32µs making 10 calls to DateTime::Format::Builder::Parser::Regex::__ANON__[DateTime/Format/Builder/Parser/Regex.pm:84], avg 3µs/call
# spent 20µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:171], avg 3µs/call # spent 42µs executing statements in 10 string evals (merged) |
| 334 | 10 | 966µs | $from->$method( %args ); # spent 966µs making 10 calls to DateTime::Format::Builder::Parser::Regex::create_parser, avg 97µs/call | ||
| 335 | } | ||||
| 336 | |||||
| 337 | =head3 merge_callbacks | ||||
| 338 | |||||
| - - | |||||
| 344 | sub merge_callbacks | ||||
| 345 | # spent 32µs within DateTime::Format::Builder::Parser::merge_callbacks which was called 5 times, avg 6µs/call:
# 5 times (32µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 316, avg 6µs/call | ||||
| 346 | 25 | 16µs | my $self = shift; | ||
| 347 | |||||
| 348 | return unless @_; # No arguments | ||||
| 349 | return unless $_[0]; # Irrelevant argument | ||||
| 350 | my @callbacks = @_; | ||||
| 351 | 5 | 22µs | if (@_ == 1) | ||
| 352 | { | ||||
| 353 | return $_[0] if ref $_[0] eq 'CODE'; | ||||
| 354 | @callbacks = @{ $_[0] } if ref $_[0] eq 'ARRAY'; | ||||
| 355 | } | ||||
| 356 | return unless @callbacks; | ||||
| 357 | |||||
| 358 | for (@callbacks) | ||||
| 359 | { | ||||
| 360 | croak "All callbacks must be coderefs!" unless ref $_ eq 'CODE'; | ||||
| 361 | } | ||||
| 362 | |||||
| 363 | return sub { | ||||
| 364 | my $rv; | ||||
| 365 | my %args = @_; | ||||
| 366 | for my $cb (@callbacks) | ||||
| 367 | { | ||||
| 368 | $rv = $cb->( %args ); | ||||
| 369 | return $rv unless $rv; | ||||
| 370 | # Ugh. Symbiotic. All but postprocessor return the date. | ||||
| 371 | $args{input} = $rv unless $args{parsed}; | ||||
| 372 | } | ||||
| 373 | $rv; | ||||
| 374 | }; | ||||
| 375 | } | ||||
| 376 | |||||
| 377 | =head2 create_multiple_parsers | ||||
| 378 | |||||
| - - | |||||
| 389 | sub create_multiple_parsers | ||||
| 390 | # spent 3.68ms (91µs+3.59) within DateTime::Format::Builder::Parser::create_multiple_parsers which was called 3 times, avg 1.23ms/call:
# 2 times (50µs+602µs) by DateTime::Format::Builder::Parser::create_parser at line 608, avg 326µs/call
# once (40µs+2.99ms) by DateTime::Format::Builder::Parser::create_parser at line 600 | ||||
| 391 | 30 | 67µs | my $class = shift; | ||
| 392 | my ($options, @specs) = @_; | ||||
| 393 | |||||
| 394 | 3 | 26µs | my $obj = $class->new; # spent 26µs making 3 calls to DateTime::Format::Builder::Parser::new, avg 9µs/call | ||
| 395 | |||||
| 396 | # Organise the specs, and transform them into parsers. | ||||
| 397 | 3 | 3.54ms | my ($lengths, $others) = $class->sort_parsers( $options, \@specs ); # spent 3.54ms making 3 calls to DateTime::Format::Builder::Parser::sort_parsers, avg 1.18ms/call | ||
| 398 | |||||
| 399 | # Merge callbacks if any. | ||||
| 400 | for ( 'preprocess' ) { | ||||
| 401 | 3 | 4µs | $options->{$_} = $class->merge_callbacks( | ||
| 402 | $options->{$_} | ||||
| 403 | ) if $options->{$_}; | ||||
| 404 | } | ||||
| 405 | # Custom fail method? | ||||
| 406 | $obj->set_fail( $options->{on_fail} ) if exists $options->{on_fail}; | ||||
| 407 | # Who's our maker? | ||||
| 408 | 3 | 14µs | $obj->set_maker( $options->{maker} ) if exists $options->{maker}; # spent 14µs making 3 calls to DateTime::Format::Builder::Parser::set_maker, avg 5µs/call | ||
| 409 | |||||
| 410 | # We don't want to save the whole options hash as a closure, since | ||||
| 411 | # that can cause a circular reference when $options->{maker} is | ||||
| 412 | # set. | ||||
| 413 | my $preprocess = $options->{preprocess}; | ||||
| 414 | |||||
| 415 | # These are the innards of a multi-parser. | ||||
| 416 | my $parser = sub { | ||||
| 417 | my ($self, $date, @args) = @_; | ||||
| 418 | return unless defined $date; | ||||
| 419 | |||||
| 420 | # Parameters common to the callbacks. Pre-prepared. | ||||
| 421 | my %param = ( | ||||
| 422 | self => $self, | ||||
| 423 | ( @args ? (args => \@args) : () ), | ||||
| 424 | ); | ||||
| 425 | |||||
| 426 | my %p; | ||||
| 427 | # Preprocess and potentially fill %p | ||||
| 428 | if ($preprocess) | ||||
| 429 | { | ||||
| 430 | $date = $preprocess->( | ||||
| 431 | input => $date, parsed => \%p, %param | ||||
| 432 | ); | ||||
| 433 | } | ||||
| 434 | |||||
| 435 | # Find length parser | ||||
| 436 | if (%$lengths) | ||||
| 437 | { | ||||
| 438 | my $length = length $date; | ||||
| 439 | my $parser = $lengths->{$length}; | ||||
| 440 | if ($parser) | ||||
| 441 | { | ||||
| 442 | # Found one, call it with _copy_ of %p | ||||
| 443 | my $dt = $parser->( $self, $date, { %p }, @args ); | ||||
| 444 | return $dt if defined $dt; | ||||
| 445 | } | ||||
| 446 | } | ||||
| 447 | # Or calls all others, with _copy_ of %p | ||||
| 448 | for my $parser (@$others) | ||||
| 449 | { | ||||
| 450 | my $dt = $parser->( $self, $date, { %p }, @args ); | ||||
| 451 | return $dt if defined $dt; | ||||
| 452 | } | ||||
| 453 | # Failed, return undef. | ||||
| 454 | return; | ||||
| 455 | }; | ||||
| 456 | 3 | 9µs | $obj->set_parser( $parser ); # spent 9µs making 3 calls to DateTime::Format::Builder::Parser::set_parser, avg 3µs/call | ||
| 457 | } | ||||
| 458 | |||||
| 459 | =head2 sort_parsers | ||||
| 460 | |||||
| - - | |||||
| 483 | sub sort_parsers | ||||
| 484 | # spent 3.54ms (194µs+3.35) within DateTime::Format::Builder::Parser::sort_parsers which was called 3 times, avg 1.18ms/call:
# 3 times (194µs+3.35ms) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 397, avg 1.18ms/call | ||||
| 485 | 18 | 49µs | my $class = shift; | ||
| 486 | my ($options, $specs) = @_; | ||||
| 487 | my (%lengths, @others); | ||||
| 488 | |||||
| 489 | for my $spec (@$specs) | ||||
| 490 | { | ||||
| 491 | # Put coderefs straight into the 'other' heap. | ||||
| 492 | 20 | 34µs | if (ref $spec eq 'CODE') | ||
| 493 | { | ||||
| 494 | push @others, $spec; | ||||
| 495 | } | ||||
| 496 | # Specifications... | ||||
| 497 | elsif (ref $spec eq 'HASH') | ||||
| 498 | { | ||||
| 499 | 24 | 78µs | if (exists $spec->{length}) | ||
| 500 | { | ||||
| 501 | 7 | 2.45ms | my $code = $class->create_single_parser( %$spec ); # spent 2.45ms making 7 calls to DateTime::Format::Builder::Parser::create_single_parser, avg 350µs/call | ||
| 502 | my @lengths = ref $spec->{length} | ||||
| 503 | ? @{ $spec->{length} } | ||||
| 504 | : ( $spec->{length} ); | ||||
| 505 | for my $length ( @lengths ) | ||||
| 506 | { | ||||
| 507 | 7 | 21µs | push @{ $lengths{$length} }, $code; | ||
| 508 | } | ||||
| 509 | } | ||||
| 510 | else | ||||
| 511 | { | ||||
| 512 | 3 | 880µs | push @others, $class->create_single_parser( %$spec ); # spent 880µs making 3 calls to DateTime::Format::Builder::Parser::create_single_parser, avg 294µs/call | ||
| 513 | } | ||||
| 514 | } | ||||
| 515 | # Something else | ||||
| 516 | else | ||||
| 517 | { | ||||
| 518 | croak "Invalid specification in list."; | ||||
| 519 | } | ||||
| 520 | } | ||||
| 521 | |||||
| 522 | 7 | 14µs | while (my ($length, $parsers) = each %lengths) # spent 14µs making 7 calls to DateTime::Format::Builder::Parser::chain_parsers, avg 2µs/call | ||
| 523 | { | ||||
| 524 | $lengths{$length} = $class->chain_parsers( $parsers ); | ||||
| 525 | } | ||||
| 526 | |||||
| 527 | return ( \%lengths, \@others ); | ||||
| 528 | } | ||||
| 529 | |||||
| 530 | sub chain_parsers | ||||
| 531 | # spent 14µs within DateTime::Format::Builder::Parser::chain_parsers which was called 7 times, avg 2µs/call:
# 7 times (14µs+0s) by DateTime::Format::Builder::Parser::sort_parsers at line 522, avg 2µs/call | ||||
| 532 | 14 | 22µs | my ($self, $parsers) = @_; | ||
| 533 | return $parsers->[0] if @$parsers == 1; | ||||
| 534 | return sub { | ||||
| 535 | my $self = shift; | ||||
| 536 | for my $parser (@$parsers) | ||||
| 537 | { | ||||
| 538 | my $rv = $self->$parser( @_ ); | ||||
| 539 | return $rv if defined $rv; | ||||
| 540 | } | ||||
| 541 | return undef; | ||||
| 542 | }; | ||||
| 543 | } | ||||
| 544 | |||||
| 545 | =head2 create_parser | ||||
| 546 | |||||
| - - | |||||
| 582 | sub create_parser | ||||
| 583 | # spent 3.73ms (48µs+3.68) within DateTime::Format::Builder::Parser::create_parser which was called 3 times, avg 1.24ms/call:
# 3 times (48µs+3.68ms) by DateTime::Format::Builder::create_parser at line 156 of DateTime/Format/Builder.pm, avg 1.24ms/call | ||||
| 584 | 15 | 17µs | my $class = shift; | ||
| 585 | if (not ref $_[0]) | ||||
| 586 | { | ||||
| 587 | # Simple case of single specification as a hash | ||||
| 588 | return $class->create_single_object( @_ ) | ||||
| 589 | } | ||||
| 590 | |||||
| 591 | # Let's see if we were given an options block | ||||
| 592 | my %options; | ||||
| 593 | while ( ref $_[0] eq 'ARRAY' ) | ||||
| 594 | { | ||||
| 595 | 6 | 15µs | my $options = shift; | ||
| 596 | %options = ( %options, @$options ); | ||||
| 597 | } | ||||
| 598 | |||||
| 599 | # Now, can we create a multi-parser out of the remaining arguments? | ||||
| 600 | 2 | 12µs | 1 | 3.03ms | if (ref $_[0] eq 'HASH' or ref $_[0] eq 'CODE') # spent 3.03ms making 1 call to DateTime::Format::Builder::Parser::create_multiple_parsers |
| 601 | { | ||||
| 602 | return $class->create_multiple_parsers( \%options, @_ ); | ||||
| 603 | } | ||||
| 604 | else | ||||
| 605 | { | ||||
| 606 | # If it wasn't a HASH or CODE, then it was (ideally) | ||||
| 607 | # a list of pairs describing a single specification. | ||||
| 608 | 2 | 652µs | return $class->create_multiple_parsers( \%options, { @_ } ); # spent 652µs making 2 calls to DateTime::Format::Builder::Parser::create_multiple_parsers, avg 326µs/call | ||
| 609 | } | ||||
| 610 | } | ||||
| 611 | |||||
| 612 | =head1 FINDING IMPLEMENTATIONS | ||||
| 613 | |||||
| - - | |||||
| 624 | # Find all our workers | ||||
| 625 | { | ||||
| 626 | 4 | 248µs | 2 | 809µs | # spent 799µs (622+177) within DateTime::Format::Builder::Parser::BEGIN@626 which was called:
# once (622µs+177µs) by DateTime::Format::MySQL::BEGIN@11 at line 626 # spent 799µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@626
# spent 11µs making 1 call to Class::Factory::Util::import |
| 627 | |||||
| 628 | 1 | 10µs | 1 | 439µs | foreach my $worker ( __PACKAGE__->subclasses ) # spent 439µs making 1 call to Class::Factory::Util::_subclasses |
| 629 | { | ||||
| 630 | 10 | 237µs | eval "use DateTime::Format::Builder::Parser::$worker;"; # spent 148µs executing statements in string eval # includes 527µs spent executing 1 call to 1 sub defined therein. # spent 147µs executing statements in string eval # includes 701µs spent executing 1 call to 1 sub defined therein. # spent 138µs executing statements in string eval # includes 466µs spent executing 1 call to 1 sub defined therein. # spent 108µs executing statements in string eval # includes 432µs spent executing 1 call to 1 sub defined therein. # spent 14µs executing statements in string eval # includes 10µs spent executing 1 call to 1 sub defined therein. | ||
| 631 | die $@ if $@; | ||||
| 632 | } | ||||
| 633 | } | ||||
| 634 | |||||
| 635 | 1 | 17µs | 1; | ||
| 636 | |||||
| 637 | __END__ | ||||
# spent 20µs within DateTime::Format::Builder::Parser::CORE:match which was called 14 times, avg 1µs/call:
# 14 times (20µs+0s) by DateTime::Format::Builder::Parser::__ANON__[/usr/share/perl5/DateTime/Format/Builder/Parser.pm:170] at line 170, avg 1µs/call |