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 | BEGIN@626 | DateTime::Format::Builder::Parser::
10 | 2 | 1 | 569µs | 3.33ms | create_single_parser | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 194µs | 3.54ms | sort_parsers | DateTime::Format::Builder::Parser::
3 | 2 | 1 | 91µs | 3.68ms | create_multiple_parsers | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 87µs | 87µs | params | DateTime::Format::Builder::Parser::
4 | 4 | 4 | 82µs | 82µs | valid_params | DateTime::Format::Builder::Parser::
14 | 2 | 1 | 65µs | 85µs | __ANON__[:170] | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 48µs | 3.73ms | create_parser | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 46µs | 46µs | params_all | DateTime::Format::Builder::Parser::
14 | 2 | 1 | 39µs | 39µs | __ANON__[:171] | DateTime::Format::Builder::Parser::
5 | 1 | 1 | 32µs | 32µs | merge_callbacks | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 32µs | 32µs | whose_params | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 26µs | 26µs | new | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 21µs | 79µs | BEGIN@8 | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 20µs | 25µs | BEGIN@2 | DateTime::Format::Builder::Parser::
14 | 1 | 1 | 20µs | 20µs | CORE:match (opcode) | DateTime::Format::Builder::Parser::
7 | 1 | 1 | 14µs | 14µs | chain_parsers | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 14µs | 14µs | set_maker | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 11µs | 65µs | BEGIN@5 | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 11µs | 48µs | BEGIN@4 | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 9µs | 36µs | BEGIN@3 | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 9µs | 9µs | set_parser | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | __ANON__[:374] | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | __ANON__[:455] | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | __ANON__[:542] | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | create_single_object | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | fail | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | maker | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | no_parser | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | on_fail | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | parse | DateTime::Format::Builder::Parser::
0 | 0 | 0 | 0s | 0s | set_fail | DateTime::Format::Builder::Parser::
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 |