Profile of /usr/local/lib/perl5/site_perl/5.10.1/Data/OptList.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For 01.HTTP.t
Run on Tue May 4 15:25:55 2010
Reported on Tue May 4 15:26:12 2010

File | /usr/local/lib/perl5/site_perl/5.10.1/Data/OptList.pm
Statements Executed | 1165
Statement Execution Time | 18.6ms

Subroutines — ordered by exclusive time
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 17.9ms | 18.7ms | Data::OptList::::BEGIN@7Data::OptList::BEGIN@7
1 | 1 | 1 | 2.44ms | 2.88ms | Data::OptList::::BEGIN@8Data::OptList::BEGIN@8
29 | 3 | 2 | 723µs | 1.22ms | Data::OptList::::mkoptData::OptList::mkopt
77 | 2 | 1 | 332µs | 496µs | Data::OptList::::__is_aData::OptList::__is_a
15 | 2 | 1 | 140µs | 1.10ms | Data::OptList::::mkopt_hashData::OptList::mkopt_hash
1 | 1 | 1 | 29µs | 35µs | Data::OptList::::BEGIN@3Data::OptList::BEGIN@3
1 | 1 | 1 | 17µs | 29µs | Data::OptList::::BEGIN@214Data::OptList::BEGIN@214
1 | 1 | 1 | 11µs | 11µs | Data::OptList::::BEGIN@131Data::OptList::BEGIN@131
1 | 1 | 1 | 9µs | 23µs | Data::OptList::::BEGIN@4Data::OptList::BEGIN@4
1 | 1 | 1 | 4µs | 4µs | Data::OptList::::BEGIN@6Data::OptList::BEGIN@6
0 | 0 | 0 | 0s | 0s | Data::OptList::::__ANON__[:143]Data::OptList::__ANON__[:143]

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

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  |
2 |  |  |  |  | package Data::OptList;
3 | 3 | 35µs | 2 | 42µs | # spent 35µs (29+7) within Data::OptList::BEGIN@3 which was called # once (29µs+7µs) by Sub::Exporter::BEGIN@7 at line 3 use strict; # spent 35µs making 1 call to Data::OptList::BEGIN@3 # spent 6µs making 1 call to strict::import
4 | 3 | 24µs | 2 | 37µs | # spent 23µs (9+14) within Data::OptList::BEGIN@4 which was called # once (9µs+14µs) by Sub::Exporter::BEGIN@7 at line 4 use warnings; # spent 23µs making 1 call to Data::OptList::BEGIN@4 # spent 14µs making 1 call to warnings::import
5 |  |  |  |  |
6 | 3 | 30µs | 1 | 4µs | # spent 4µs within Data::OptList::BEGIN@6 which was called # once (4µs+0s) by Sub::Exporter::BEGIN@7 at line 6 use List::Util (); # spent 4µs making 1 call to Data::OptList::BEGIN@6
7 | 3 | 15.8ms | 1 | 18.7ms | # spent 18.7ms (17.9+741µs) within Data::OptList::BEGIN@7 which was called # once (17.9ms+741µs) by Sub::Exporter::BEGIN@7 at line 7 use Params::Util (); # spent 18.7ms making 1 call to Data::OptList::BEGIN@7
8 | 3 | 304µs | 2 | 2.92ms | # spent 2.88ms (2.44+441µs) within Data::OptList::BEGIN@8 which was called # once (2.44ms+441µs) by Sub::Exporter::BEGIN@7 at line 8 use Sub::Install 0.92 (); # spent 2.88ms making 1 call to Data::OptList::BEGIN@8 # spent 32µs making 1 call to UNIVERSAL::VERSION
9 |  |  |  |  |
10 |  |  |  |  | =head1 NAME
11 |  |  |  |  |
12 |  |  |  |  | Data::OptList - parse and validate simple name/value option pairs
13 |  |  |  |  |
14 |  |  |  |  | =head1 VERSION
15 |  |  |  |  |
16 |  |  |  |  | version 0.104
17 |  |  |  |  |
18 |  |  |  |  | =cut
19 |  |  |  |  |
20 | 1 | 1µs |  |  | our $VERSION = '0.104';
21 |  |  |  |  |
22 |  |  |  |  | =head1 SYNOPSIS
23 |  |  |  |  |
24 |  |  |  |  | use Data::OptList;
25 |  |  |  |  |
26 |  |  |  |  | my $options = Data::Optlist::mkopt([
27 |  |  |  |  | qw(key1 key2 key3 key4),
28 |  |  |  |  | key5 => { ... },
29 |  |  |  |  | key6 => [ ... ],
30 |  |  |  |  | key7 => sub { ... },
31 |  |  |  |  | key8 => { ... },
32 |  |  |  |  | key8 => [ ... ],
33 |  |  |  |  | ]);
34 |  |  |  |  |
35 |  |  |  |  | ...is the same thing, more or less, as:
36 |  |  |  |  |
37 |  |  |  |  | my $options = [
38 |  |  |  |  | [ key1 => undef, ],
39 |  |  |  |  | [ key2 => undef, ],
40 |  |  |  |  | [ key3 => undef, ],
41 |  |  |  |  | [ key4 => undef, ],
42 |  |  |  |  | [ key5 => { ... }, ],
43 |  |  |  |  | [ key6 => [ ... ], ],
44 |  |  |  |  | [ key7 => sub { ... }, ],
45 |  |  |  |  | [ key8 => { ... }, ],
46 |  |  |  |  | [ key8 => [ ... ], ],
47 |  |  |  |  | ]);
48 |  |  |  |  |
49 |  |  |  |  | =head1 DESCRIPTION
50 |  |  |  |  |
51 |  |  |  |  | Hashes are great for storing named data, but if you want more than one entry
52 |  |  |  |  | for a name, you have to use a list of pairs. Even then, this is really boring
53 |  |  |  |  | to write:
54 |  |  |  |  |
55 |  |  |  |  | $values = [
56 |  |  |  |  | foo => undef,
57 |  |  |  |  | bar => undef,
58 |  |  |  |  | baz => undef,
59 |  |  |  |  | xyz => { ... },
60 |  |  |  |  | ];
61 |  |  |  |  |
62 |  |  |  |  | Just look at all those undefs! Don't worry, we can get rid of those:
63 |  |  |  |  |
64 |  |  |  |  | $values = [
65 |  |  |  |  | map { $_ => undef } qw(foo bar baz),
66 |  |  |  |  | xyz => { ... },
67 |  |  |  |  | ];
68 |  |  |  |  |
69 |  |  |  |  | Aaaauuugh! We've saved a little typing, but now it requires thought to read,
70 |  |  |  |  | and thinking is even worse than typing... and it's got a bug! It looked right,
71 |  |  |  |  | didn't it? Well, the C<< xyz => { ... } >> gets consumed by the map, and we
72 |  |  |  |  | don't get the data we wanted.
73 |  |  |  |  |
74 |  |  |  |  | With Data::OptList, you can do this instead:
75 |  |  |  |  |
76 |  |  |  |  | $values = Data::OptList::mkopt([
77 |  |  |  |  | qw(foo bar baz),
78 |  |  |  |  | xyz => { ... },
79 |  |  |  |  | ]);
80 |  |  |  |  |
81 |  |  |  |  | This works by assuming that any defined scalar is a name and any reference
82 |  |  |  |  | following a name is its value.
83 |  |  |  |  |
84 |  |  |  |  | =head1 FUNCTIONS
85 |  |  |  |  |
86 |  |  |  |  | =head2 mkopt
87 |  |  |  |  |
88 |  |  |  |  | my $opt_list = Data::OptList::mkopt(
89 |  |  |  |  | $input,
90 |  |  |  |  | $moniker,
91 |  |  |  |  | $require_unique,
92 |  |  |  |  | $must_be,
93 |  |  |  |  | );
94 |  |  |  |  |
95 |  |  |  |  | This produces an array of arrays; the inner arrays are name/value pairs.
96 |  |  |  |  | Values will be either "undef" or a reference.
97 |  |  |  |  |
98 |  |  |  |  | Valid values for C<$input>:
99 |  |  |  |  |
100 |  |  |  |  | undef -> []
101 |  |  |  |  | hashref -> [ [ key1 => value1 ] ... ] # non-ref values become undef
102 |  |  |  |  | arrayref -> every value followed by a ref becomes a pair: [ value => ref ]
103 |  |  |  |  | every value followed by undef becomes a pair: [ value => undef ]
104 |  |  |  |  | otherwise, it becomes [ value => undef ] like so:
105 |  |  |  |  | [ "a", "b", [ 1, 2 ] ] -> [ [ a => undef ], [ b => [ 1, 2 ] ] ]
106 |  |  |  |  |
107 |  |  |  |  | C<$moniker> is a name describing the data, which will be used in error
108 |  |  |  |  | messages.
109 |  |  |  |  |
110 |  |  |  |  | If C<$require_unique> is true, an error will be thrown if any name is given
111 |  |  |  |  | more than once.
112 |  |  |  |  |
113 |  |  |  |  | C<$must_be> is either a scalar or array of scalars; it defines what kind(s) of
114 |  |  |  |  | refs may be values. If an invalid value is found, an exception is thrown. If
115 |  |  |  |  | no value is passed for this argument, any reference is valid. If C<$must_be>
116 |  |  |  |  | specifies that values must be CODE, HASH, ARRAY, or SCALAR, then Params::Util
117 |  |  |  |  | is used to check whether the given value can provide that interface.
118 |  |  |  |  | Otherwise, it checks that the given value is an object of the kind.
119 |  |  |  |  |
120 |  |  |  |  | In other words:
121 |  |  |  |  |
122 |  |  |  |  | [ qw(SCALAR HASH Object::Known) ]
123 |  |  |  |  |
124 |  |  |  |  | Means:
125 |  |  |  |  |
126 |  |  |  |  | _SCALAR0($value) or _HASH($value) or _INSTANCE($value, 'Object::Known')
127 |  |  |  |  |
128 |  |  |  |  | =cut
129 |  |  |  |  |
130 | 1 | 200ns |  |  | my %test_for;
131 |  |  |  |  | # spent 11µs within Data::OptList::BEGIN@131 which was called # once (11µs+0s) by Sub::Exporter::BEGIN@7 at line 138 BEGIN {
132 | 1 | 12µs |  |  | %test_for = (
133 |  |  |  |  | CODE => \&Params::Util::_CODELIKE, ## no critic
134 |  |  |  |  | HASH => \&Params::Util::_HASHLIKE, ## no critic
135 |  |  |  |  | ARRAY => \&Params::Util::_ARRAYLIKE, ## no critic
136 |  |  |  |  | SCALAR => \&Params::Util::_SCALAR0, ## no critic
137 |  |  |  |  | );
138 | 1 | 1.05ms | 1 | 11µs | } # spent 11µs making 1 call to Data::OptList::BEGIN@131
139 |  |  |  |  |
140 |  |  |  |  | # spent 496µs (332+164) within Data::OptList::__is_a which was called 77 times, avg 6µs/call: # 41 times (169µs+-169µs) by List::Util::first at line 143, avg 0s/call # 36 times (163µs+333µs) by Data::OptList::mkopt at line 178, avg 14µs/call sub __is_a {
141 | 195 | 338µs |  |  | my ($got, $expected) = @_;
142 |  |  |  |  |
143 | 41 | 145µs | 77 | 333µs | return List::Util::first { __is_a($got, $_) } @$expected if ref $expected; # spent 333µs making 36 calls to List::Util::first, avg 9µs/call # spent 198µs making 41 calls to Data::OptList::__is_a, avg 5µs/call, recursion: max depth 1, time 198µs
144 |  |  |  |  |
145 |  |  |  |  | return defined (
146 |  |  |  |  | exists($test_for{$expected}) # spent 15µs making 31 calls to Params::Util::_CODELIKE, avg 497ns/call # spent 8µs making 5 calls to Params::Util::_HASHLIKE, avg 2µs/call # spent 6µs making 5 calls to Params::Util::_ARRAYLIKE, avg 1µs/call
147 |  |  |  |  | ? $test_for{$expected}->($got)
148 |  |  |  |  | : Params::Util::_INSTANCE($got, $expected) ## no critic
149 |  |  |  |  | );
150 |  |  |  |  | }
151 |  |  |  |  |
152 |  |  |  |  | # spent 1.22ms (723µs+496µs) within Data::OptList::mkopt which was called 29 times, avg 42µs/call: # 11 times (465µs+496µs) by Data::OptList::mkopt_hash at line 203, avg 87µs/call # 11 times (126µs+0s) by Sub::Exporter::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/Sub/Exporter.pm:756] at line 735 of Sub/Exporter.pm, avg 11µs/call # 7 times (131µs+0s) by Sub::Exporter::_expand_group at line 505 of Sub/Exporter.pm, avg 19µs/call sub mkopt {
153 | 232 | 248µs |  |  | my ($opt_list, $moniker, $require_unique, $must_be) = @_;
154 |  |  |  |  |
155 |  |  |  |  | return [] unless $opt_list;
156 |  |  |  |  |
157 |  |  |  |  | $opt_list = [
158 |  |  |  |  | map { $_ => (ref $opt_list->{$_} ? $opt_list->{$_} : ()) } keys %$opt_list
159 |  |  |  |  | ] if ref $opt_list eq 'HASH';
160 |  |  |  |  |
161 |  |  |  |  | my @return;
162 |  |  |  |  | my %seen;
163 |  |  |  |  |
164 | 534 | 321µs |  |  | for (my $i = 0; $i < @$opt_list; $i++) { ## no critic
165 | 1 | 36µs |  |  | my $name = $opt_list->[$i];
166 |  |  |  |  | my $value;
167 |  |  |  |  |
168 |  |  |  |  | if ($require_unique) {
169 |  |  |  |  | Carp::croak "multiple definitions provided for $name" if $seen{$name}++;
170 |  |  |  |  | }
171 |  |  |  |  |
172 | 41 | 5µs |  |  | if ($i == $#$opt_list) { $value = undef; }
173 |  |  |  |  | elsif (not defined $opt_list->[$i+1]) { $value = undef; $i++ }
174 |  |  |  |  | elsif (ref $opt_list->[$i+1]) { $value = $opt_list->[++$i] }
175 |  |  |  |  | else { $value = undef; }
176 |  |  |  |  |
177 | 36 | 37µs |  |  | if ($must_be and defined $value) {
178 |  |  |  |  | unless (__is_a($value, $must_be)) { # spent 496µs making 36 calls to Data::OptList::__is_a, avg 14µs/call
179 |  |  |  |  | my $ref = ref $value;
180 |  |  |  |  | Carp::croak "$ref-ref values are not valid in $moniker opt list";
181 |  |  |  |  | }
182 |  |  |  |  | }
183 |  |  |  |  |
184 |  |  |  |  | push @return, [ $name => $value ];
185 |  |  |  |  | }
186 |  |  |  |  |
187 |  |  |  |  | return \@return;
188 |  |  |  |  | }
189 |  |  |  |  |
190 |  |  |  |  | =head2 mkopt_hash
191 |  |  |  |  |
192 |  |  |  |  | my $opt_hash = Data::OptList::mkopt_hash($input, $moniker, $must_be);
193 |  |  |  |  |
194 |  |  |  |  | Given valid C<L</mkopt>> input, this routine returns a reference to a hash. It
195 |  |  |  |  | will throw an exception if any name has more than one value.
196 |  |  |  |  |
197 |  |  |  |  | =cut
198 |  |  |  |  |
199 |  |  |  |  | # spent 1.10ms (140µs+961µs) within Data::OptList::mkopt_hash which was called 15 times, avg 73µs/call: # 10 times (107µs+753µs) by Sub::Exporter::_rewrite_build_config at line 672 of Sub/Exporter.pm, avg 86µs/call # 5 times (33µs+209µs) by Sub::Exporter::_rewrite_build_config at line 685 of Sub/Exporter.pm, avg 48µs/call sub mkopt_hash {
200 | 63 | 133µs |  |  | my ($opt_list, $moniker, $must_be) = @_;
201 |  |  |  |  | return {} unless $opt_list;
202 |  |  |  |  |
203 |  |  |  |  | $opt_list = mkopt($opt_list, $moniker, 1, $must_be); # spent 961µs making 11 calls to Data::OptList::mkopt, avg 87µs/call
204 |  |  |  |  | my %hash = map { $_->[0] => $_->[1] } @$opt_list;
205 |  |  |  |  | return \%hash;
206 |  |  |  |  | }
207 |  |  |  |  |
208 |  |  |  |  | =head1 EXPORTS
209 |  |  |  |  |
210 |  |  |  |  | Both C<mkopt> and C<mkopt_hash> may be exported on request.
211 |  |  |  |  |
212 |  |  |  |  | =cut
213 |  |  |  |  |
214 |  |  |  |  | # spent 29µs (17+12) within Data::OptList::BEGIN@214 which was called # once (17µs+12µs) by Sub::Exporter::BEGIN@7 at line 218 BEGIN {
215 | 1 | 10µs | 1 | 12µs | *import = Sub::Install::exporter { # spent 12µs making 1 call to Sub::Install::exporter
216 |  |  |  |  | exports => [qw(mkopt mkopt_hash)],
217 |  |  |  |  | };
218 | 1 | 49µs | 1 | 29µs | } # spent 29µs making 1 call to Data::OptList::BEGIN@214
219 |  |  |  |  |
220 |  |  |  |  | =head1 AUTHOR
221 |  |  |  |  |
222 |  |  |  |  | Ricardo SIGNES, C<< <rjbs@cpan.org> >>
223 |  |  |  |  |
224 |  |  |  |  | =head1 BUGS
225 |  |  |  |  |
226 |  |  |  |  | Please report any bugs or feature requests at L<http://rt.cpan.org>. I will be
227 |  |  |  |  | notified, and then you'll automatically be notified of progress on your bug as
228 |  |  |  |  | I make changes.
229 |  |  |  |  |
230 |  |  |  |  | =head1 COPYRIGHT
231 |  |  |  |  |
232 |  |  |  |  | Copyright 2006-2007, Ricardo SIGNES. This program is free software; you can
233 |  |  |  |  | redistribute it and/or modify it under the same terms as Perl itself.
234 |  |  |  |  |
235 |  |  |  |  | =cut
236 |  |  |  |  |
237 | 1 | 6µs |  |  | 1;