Filename | /usr/share/perl5/DateTime/Format/Builder/Parser.pm |
Statements | Executed 563 statements in 5.89ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 658µs | 868µs | BEGIN@626 | DateTime::Format::Builder::Parser::
10 | 2 | 1 | 552µs | 3.23ms | create_single_parser | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 195µs | 3.44ms | sort_parsers | DateTime::Format::Builder::Parser::
4 | 4 | 4 | 126µs | 126µs | valid_params | DateTime::Format::Builder::Parser::
3 | 2 | 1 | 89µs | 3.59ms | create_multiple_parsers | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 86µs | 86µs | params | DateTime::Format::Builder::Parser::
14 | 2 | 1 | 61µs | 81µs | __ANON__[:170] | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 44µs | 44µs | params_all | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 42µs | 3.63ms | create_parser | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 37µs | 37µs | new | DateTime::Format::Builder::Parser::
14 | 2 | 1 | 35µs | 35µs | __ANON__[:171] | DateTime::Format::Builder::Parser::
5 | 1 | 1 | 32µs | 32µs | merge_callbacks | DateTime::Format::Builder::Parser::
10 | 1 | 1 | 30µs | 30µs | whose_params | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 23µs | 88µs | BEGIN@8 | DateTime::Format::Builder::Parser::
14 | 1 | 1 | 20µs | 20µs | CORE:match (opcode) | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 20µs | 25µs | BEGIN@2 | DateTime::Format::Builder::Parser::
7 | 1 | 1 | 16µs | 16µs | chain_parsers | DateTime::Format::Builder::Parser::
3 | 1 | 1 | 13µs | 13µs | set_maker | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 12µs | 74µs | BEGIN@5 | DateTime::Format::Builder::Parser::
1 | 1 | 1 | 11µs | 51µ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 | 44µs | 2 | 29µ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 | 31µs | 2 | 63µ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 27µs making 1 call to vars::import |
4 | 3 | 35µs | 2 | 91µs | # spent 51µs (11+40) within DateTime::Format::Builder::Parser::BEGIN@4 which was called:
# once (11µs+40µs) by DateTime::Format::MySQL::BEGIN@11 at line 4 # spent 51µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@4
# spent 40µs making 1 call to Exporter::import |
5 | 1 | 62µs | # spent 74µs (12+62) within DateTime::Format::Builder::Parser::BEGIN@5 which was called:
# once (12µs+62µs) by DateTime::Format::MySQL::BEGIN@11 at line 7 # spent 62µs making 1 call to Exporter::import | ||
6 | validate SCALAR CODEREF UNDEF ARRAYREF | ||||
7 | 3 | 34µs | 1 | 74µs | ); # spent 74µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@5 |
8 | 3 | 2.53ms | 2 | 153µs | # spent 88µs (23+65) within DateTime::Format::Builder::Parser::BEGIN@8 which was called:
# once (23µs+65µs) by DateTime::Format::MySQL::BEGIN@11 at line 8 # spent 88µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@8
# spent 65µs making 1 call to Exporter::import |
9 | |||||
10 | =head1 NAME | ||||
11 | |||||
- - | |||||
27 | 1 | 1µ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 37µs within DateTime::Format::Builder::Parser::new which was called 3 times, avg 12µs/call:
# 3 times (37µs+0s) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 394, avg 12µs/call | ||||
51 | 15 | 46µ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 13µs within DateTime::Format::Builder::Parser::set_maker which was called 3 times, avg 4µs/call:
# 3 times (13µs+0s) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 408, avg 4µs/call | ||||
66 | 15 | 16µ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 | 13µ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 | 2µs | my @callbacks = qw( on_match on_fail postprocess preprocess ); | ||
122 | |||||
123 | { | ||||
124 | |||||
125 | 1 | 500ns | =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 81µs (61+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 6µs/call
# 7 times (26µs+10µs) by Params::Validate::_validate at line 333, avg 5µs/call # spent 20µs making 14 calls to DateTime::Format::Builder::Parser::CORE:match, avg 1µs/call |
171 | 14 | 69µs | # spent 35µ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 (18µs+0s) by Params::Validate::_validate at line 311, avg 3µs/call
# 7 times (17µs+0s) by Params::Validate::_validate at line 333, avg 2µs/call | ||
172 | } | ||||
173 | }, | ||||
174 | |||||
175 | # Stuff used by callbacks | ||||
176 | label => { type => SCALAR, optional => 1 }, | ||||
177 | 3 | 23µs | ( map { $_ => { type => CODEREF|ARRAYREF, optional => 1 } } @callbacks ), | ||
178 | }, | ||||
179 | ); | ||||
180 | |||||
181 | =head3 params | ||||
182 | |||||
- - | |||||
191 | sub params | ||||
192 | # spent 86µs within DateTime::Format::Builder::Parser::params which was called 10 times, avg 9µs/call:
# 10 times (86µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 333, avg 9µs/call | ||||
193 | 30 | 103µ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 44µs within DateTime::Format::Builder::Parser::params_all which was called 10 times, avg 4µs/call:
# 10 times (44µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 311, avg 4µs/call | ||||
210 | 14 | 62µ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 126µs within DateTime::Format::Builder::Parser::valid_params which was called 4 times, avg 31µs/call:
# once (79µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1 at line 84 of DateTime/Format/Builder/Parser/Dispatch.pm
# once (20µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.6 at line 101 of DateTime/Format/Builder/Parser/Regex.pm
# once (14µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.5 at line 71 of DateTime/Format/Builder/Parser/Quick.pm
# once (12µs+0s) by DateTime::Format::Builder::Parser::BEGIN@1.7 at line 35 of DateTime/Format/Builder/Parser/Strptime.pm | ||||
229 | 28 | 129µ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 | 14µ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 30µs within DateTime::Format::Builder::Parser::whose_params which was called 10 times, avg 3µs/call:
# 10 times (30µs+0s) by DateTime::Format::Builder::Parser::create_single_parser at line 323, avg 3µs/call | ||||
256 | 20 | 41µ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.23ms (552µs+2.68) within DateTime::Format::Builder::Parser::create_single_parser which was called 10 times, avg 323µs/call:
# 7 times (423µs+2.03ms) by DateTime::Format::Builder::Parser::sort_parsers at line 501, avg 350µs/call
# 3 times (129µs+652µs) by DateTime::Format::Builder::Parser::sort_parsers at line 512, avg 260µs/call | ||||
307 | 120 | 809µ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 | 447µs | 44 | 955µs | my %args = validate( @_, params_all() ); # spent 818µs making 10 calls to Params::Validate::_validate, avg 82µs/call
# spent 45µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:170], avg 6µs/call
# spent 44µs making 10 calls to DateTime::Format::Builder::Parser::params_all, avg 4µs/call
# spent 30µ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 43µs executing statements in 10 string evals (merged) |
312 | |||||
313 | # Determine variables for ease of reference. | ||||
314 | for (@callbacks) | ||||
315 | { | ||||
316 | 40 | 49µ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 | 30µs | $from = whose_params( $_ ); # spent 30µ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 | 35µs | my $method = $from->can( "create_parser" ) # spent 35µ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 | 431µs | 44 | 921µs | %args = validate( @args, $from->params() ); # spent 757µs making 10 calls to Params::Validate::_validate, avg 76µs/call
# spent 86µs making 10 calls to DateTime::Format::Builder::Parser::params, avg 9µs/call
# spent 36µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:170], avg 5µs/call
# spent 25µs making 10 calls to DateTime::Format::Builder::Parser::Regex::__ANON__[DateTime/Format/Builder/Parser/Regex.pm:84], avg 2µs/call
# spent 17µs making 7 calls to DateTime::Format::Builder::Parser::__ANON__[DateTime/Format/Builder/Parser.pm:171], avg 2µs/call # spent 49µs executing statements in 10 string evals (merged) |
334 | 10 | 876µs | $from->$method( %args ); # spent 876µs making 10 calls to DateTime::Format::Builder::Parser::Regex::create_parser, avg 88µ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 | 15µs | my $self = shift; | ||
347 | |||||
348 | return unless @_; # No arguments | ||||
349 | return unless $_[0]; # Irrelevant argument | ||||
350 | my @callbacks = @_; | ||||
351 | 5 | 23µ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.59ms (89µs+3.50) within DateTime::Format::Builder::Parser::create_multiple_parsers which was called 3 times, avg 1.20ms/call:
# 2 times (48µs+578µs) by DateTime::Format::Builder::Parser::create_parser at line 608, avg 313µs/call
# once (41µs+2.92ms) by DateTime::Format::Builder::Parser::create_parser at line 600 | ||||
391 | 30 | 67µs | my $class = shift; | ||
392 | my ($options, @specs) = @_; | ||||
393 | |||||
394 | 3 | 37µs | my $obj = $class->new; # spent 37µs making 3 calls to DateTime::Format::Builder::Parser::new, avg 12µs/call | ||
395 | |||||
396 | # Organise the specs, and transform them into parsers. | ||||
397 | 3 | 3.44ms | my ($lengths, $others) = $class->sort_parsers( $options, \@specs ); # spent 3.44ms making 3 calls to DateTime::Format::Builder::Parser::sort_parsers, avg 1.15ms/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 | 13µs | $obj->set_maker( $options->{maker} ) if exists $options->{maker}; # spent 13µs making 3 calls to DateTime::Format::Builder::Parser::set_maker, avg 4µ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.44ms (195µs+3.25) within DateTime::Format::Builder::Parser::sort_parsers which was called 3 times, avg 1.15ms/call:
# 3 times (195µs+3.25ms) by DateTime::Format::Builder::Parser::create_multiple_parsers at line 397, avg 1.15ms/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 | 75µ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 | 780µs | push @others, $class->create_single_parser( %$spec ); # spent 780µs making 3 calls to DateTime::Format::Builder::Parser::create_single_parser, avg 260µs/call | ||
513 | } | ||||
514 | } | ||||
515 | # Something else | ||||
516 | else | ||||
517 | { | ||||
518 | croak "Invalid specification in list."; | ||||
519 | } | ||||
520 | } | ||||
521 | |||||
522 | 7 | 16µs | while (my ($length, $parsers) = each %lengths) # spent 16µ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 16µs within DateTime::Format::Builder::Parser::chain_parsers which was called 7 times, avg 2µs/call:
# 7 times (16µs+0s) by DateTime::Format::Builder::Parser::sort_parsers at line 522, avg 2µs/call | ||||
532 | 14 | 24µ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.63ms (42µs+3.59) within DateTime::Format::Builder::Parser::create_parser which was called 3 times, avg 1.21ms/call:
# 3 times (42µs+3.59ms) by DateTime::Format::Builder::create_parser at line 156 of DateTime/Format/Builder.pm, avg 1.21ms/call | ||||
584 | 15 | 19µ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 | 11µ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 | 11µs | 1 | 2.96ms | if (ref $_[0] eq 'HASH' or ref $_[0] eq 'CODE') # spent 2.96ms 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 | 625µs | return $class->create_multiple_parsers( \%options, { @_ } ); # spent 625µs making 2 calls to DateTime::Format::Builder::Parser::create_multiple_parsers, avg 313µs/call | ||
609 | } | ||||
610 | } | ||||
611 | |||||
612 | =head1 FINDING IMPLEMENTATIONS | ||||
613 | |||||
- - | |||||
624 | # Find all our workers | ||||
625 | { | ||||
626 | 4 | 188µs | 2 | 880µs | # spent 868µs (658+209) within DateTime::Format::Builder::Parser::BEGIN@626 which was called:
# once (658µs+209µs) by DateTime::Format::MySQL::BEGIN@11 at line 626 # spent 868µs making 1 call to DateTime::Format::Builder::Parser::BEGIN@626
# spent 12µs making 1 call to Class::Factory::Util::import |
627 | |||||
628 | 1 | 7µs | 1 | 358µs | foreach my $worker ( __PACKAGE__->subclasses ) # spent 358µs making 1 call to Class::Factory::Util::_subclasses |
629 | { | ||||
630 | 10 | 254µs | eval "use DateTime::Format::Builder::Parser::$worker;"; # spent 182µs executing statements in string eval # includes 811µs spent executing 1 call to 1 sub defined therein. # spent 116µs executing statements in string eval # includes 460µs spent executing 1 call to 1 sub defined therein. # spent 116µs executing statements in string eval # includes 486µs spent executing 1 call to 1 sub defined therein. # spent 114µs executing statements in string eval # includes 437µs spent executing 1 call to 1 sub defined therein. # spent 14µs executing statements in string eval # includes 16µs spent executing 1 call to 1 sub defined therein. | ||
631 | die $@ if $@; | ||||
632 | } | ||||
633 | } | ||||
634 | |||||
635 | 1 | 23µ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 |