← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 16:10:05 2022
Reported on Wed Dec 14 16:12:57 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm
StatementsExecuted 5736249 statements in 4.96s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
263355211.53s2.67sMojo::Parameters::::cloneMojo::Parameters::clone
256012211.28s1.94sMojo::Parameters::::to_stringMojo::Parameters::to_string
30998222658ms958msMojo::Parameters::::newMojo::Parameters::new
51936721653ms653msMojo::Parameters::::pairsMojo::Parameters::pairs
48860121319ms319msMojo::Parameters::::__ANON__[:3]Mojo::Parameters::__ANON__[:3]
11132µs206µsMojo::Parameters::::BEGIN@2Mojo::Parameters::BEGIN@2
11112µs42µsMojo::Parameters::::BEGIN@3Mojo::Parameters::BEGIN@3
1117µs145µsMojo::Parameters::::BEGIN@5Mojo::Parameters::BEGIN@5
0000s0sMojo::Parameters::::appendMojo::Parameters::append
0000s0sMojo::Parameters::::every_paramMojo::Parameters::every_param
0000s0sMojo::Parameters::::mergeMojo::Parameters::merge
0000s0sMojo::Parameters::::namesMojo::Parameters::names
0000s0sMojo::Parameters::::paramMojo::Parameters::param
0000s0sMojo::Parameters::::parseMojo::Parameters::parse
0000s0sMojo::Parameters::::removeMojo::Parameters::remove
0000s0sMojo::Parameters::::to_hashMojo::Parameters::to_hash
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Mojo::Parameters;
22122µs2380µs
# spent 206µs (32+174) within Mojo::Parameters::BEGIN@2 which was called: # once (32µs+174µs) by Mojo::URL::BEGIN@5 at line 2
use Mojo::Base -base;
# spent 206µs making 1 call to Mojo::Parameters::BEGIN@2 # spent 174µs making 1 call to Mojo::Base::import
3488603832ms272µs
# spent 319ms within Mojo::Parameters::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm:3] which was called 488601 times, avg 653ns/call: # 247494 times (170ms+0s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 685ns/call # 241107 times (149ms+0s) by Mojo::URL::query at line 102 of Mojo/URL.pm, avg 620ns/call # spent 42µs (12+30) within Mojo::Parameters::BEGIN@3 which was called: # once (12µs+30µs) by Mojo::URL::BEGIN@5 at line 3
use overload '@{}' => sub { shift->pairs }, bool => sub {1}, '""' => sub { shift->to_string }, fallback => 1;
# spent 42µs making 1 call to Mojo::Parameters::BEGIN@3 # spent 30µs making 1 call to overload::import
4
521.70ms2283µs
# spent 145µs (7+138) within Mojo::Parameters::BEGIN@5 which was called: # once (7µs+138µs) by Mojo::URL::BEGIN@5 at line 5
use Mojo::Util qw(decode encode url_escape url_unescape);
# spent 145µs making 1 call to Mojo::Parameters::BEGIN@5 # spent 138µs making 1 call to Exporter::import
6
713µs161µshas charset => 'UTF-8';
# spent 61µs making 1 call to Mojo::Parameters::has
8
9sub append {
10 my $self = shift;
11
12 my $old = $self->pairs;
13 my @new = @_ == 1 ? @{shift->pairs} : @_;
14 while (my ($name, $value) = splice @new, 0, 2) {
15
16 # Multiple values
17 if (ref $value eq 'ARRAY') { push @$old, $name => $_ // '' for @$value }
18
19 # Single value
20 elsif (defined $value) { push @$old, $name => $value }
21 }
22
23 return $self;
24}
25
26
# spent 2.67s (1.53+1.14) within Mojo::Parameters::clone which was called 263355 times, avg 10µs/call: # 247494 times (1.44s+1.08s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 10µs/call # 15861 times (92.9ms+58.0ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 10µs/call
sub clone {
2726335538.2ms my $self = shift;
28
29263355217ms263355800ms my $clone = $self->new;
# spent 800ms making 263355 calls to Mojo::Parameters::new, avg 3µs/call
30263355235ms if (exists $self->{charset}) { $clone->{charset} = $self->{charset} }
31263355129ms if (defined $self->{string}) { $clone->{string} = $self->{string} }
32263355341ms263355340ms else { $clone->{pairs} = [@{$self->pairs}] }
# spent 340ms making 263355 calls to Mojo::Parameters::pairs, avg 1µs/call
33
34263355418ms return $clone;
35}
36
37sub every_param {
38 my ($self, $name) = @_;
39
40 my @values;
41 my $pairs = $self->pairs;
42 for (my $i = 0; $i < @$pairs; $i += 2) {
43 push @values, $pairs->[$i + 1] if $pairs->[$i] eq $name;
44 }
45
46 return \@values;
47}
48
49sub merge {
50 my $self = shift;
51
52 my $merge = @_ == 1 ? shift->to_hash : {@_};
53 for my $name (sort keys %$merge) {
54 my $value = $merge->{$name};
55 defined $value ? $self->param($name => $value) : $self->remove($name);
56 }
57
58 return $self;
59}
60
61sub names { [sort keys %{shift->to_hash}] }
62
63309982615ms309982300ms
# spent 958ms (658+300) within Mojo::Parameters::new which was called 309982 times, avg 3µs/call: # 263355 times (550ms+249ms) by Mojo::Parameters::clone at line 29, avg 3µs/call # 46627 times (108ms+50.7ms) by Mojo::URL::query at line 102 of Mojo/URL.pm, avg 3µs/call
sub new { @_ > 1 ? shift->SUPER::new->parse(@_) : shift->SUPER::new }
# spent 300ms making 309982 calls to Mojo::Base::new, avg 967ns/call
64
65
# spent 653ms within Mojo::Parameters::pairs which was called 519367 times, avg 1µs/call: # 263355 times (340ms+0s) by Mojo::Parameters::clone at line 32, avg 1µs/call # 256012 times (313ms+0s) by Mojo::Parameters::to_string at line 157, avg 1µs/call
sub pairs {
6651936770.3ms my $self = shift;
67
68 # Replace parameters
6951936768.3ms if (@_) {
70 $self->{pairs} = shift;
71 delete $self->{string};
72 return $self;
73 }
74
75 # Parse string
76519367152ms if (defined(my $str = delete $self->{string})) {
77 my $pairs = $self->{pairs} = [];
78 return $pairs unless length $str;
79
80 my $charset = $self->charset;
81 for my $pair (split /&/, $str) {
82 next unless $pair =~ /^([^=]+)(?:=(.*))?$/;
83 my ($name, $value) = ($1, $2 // '');
84
85 # Replace "+" with whitespace, unescape and decode
86 s/\+/ /g for $name, $value;
87 $name = url_unescape $name;
88 $name = decode($charset, $name) // $name if $charset;
89 $value = url_unescape $value;
90 $value = decode($charset, $value) // $value if $charset;
91
92 push @$pairs, $name, $value;
93 }
94 }
95
96519367757ms return $self->{pairs} //= [];
97}
98
99sub param {
100 my ($self, $name) = (shift, shift);
101 return $self->every_param($name)->[-1] unless @_;
102 $self->remove($name);
103 return $self->append($name => ref $_[0] eq 'ARRAY' ? $_[0] : [@_]);
104}
105
106sub parse {
107 my $self = shift;
108
109 # Pairs
110 return $self->append(@_) if @_ > 1;
111
112 # String
113 $self->{string} = shift;
114 return $self;
115}
116
117sub remove {
118 my ($self, $name) = @_;
119 my $pairs = $self->pairs;
120 my $i = 0;
121 $pairs->[$i] eq $name ? splice @$pairs, $i, 2 : ($i += 2) while $i < @$pairs;
122 return $self;
123}
124
125sub to_hash {
126 my $self = shift;
127
128 my %hash;
129 my $pairs = $self->pairs;
130 for (my $i = 0; $i < @$pairs; $i += 2) {
131 my ($name, $value) = @{$pairs}[$i, $i + 1];
132
133 # Array
134 if (exists $hash{$name}) {
135 $hash{$name} = [$hash{$name}] if ref $hash{$name} ne 'ARRAY';
136 push @{$hash{$name}}, $value;
137 }
138
139 # String
140 else { $hash{$name} = $value }
141 }
142
143 return \%hash;
144}
145
146
# spent 1.94s (1.28+663ms) within Mojo::Parameters::to_string which was called 256012 times, avg 8µs/call: # 240151 times (1.20s+607ms) by Mojo::URL::path_query at line 92 of Mojo/URL.pm, avg 8µs/call # 15861 times (81.7ms+56.0ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 9µs/call
sub to_string {
14725601237.7ms my $self = shift;
148
149 # String (RFC 3986)
150256012267ms256012350ms my $charset = $self->charset;
# spent 350ms making 256012 calls to Mojo::Parameters::charset, avg 1µs/call
151256012111ms if (defined(my $str = $self->{string})) {
152 $str = encode $charset, $str if $charset;
153 return url_escape $str, '^A-Za-z0-9\-._~%!$&\'()*+,;=:@/?';
154 }
155
156 # Build pairs (HTML Living Standard)
157256012193ms256012313ms my $pairs = $self->pairs;
# spent 313ms making 256012 calls to Mojo::Parameters::pairs, avg 1µs/call
158256012482ms return '' unless @$pairs;
159 my @pairs;
160 for (my $i = 0; $i < @$pairs; $i += 2) {
161 my ($name, $value) = @{$pairs}[$i, $i + 1];
162
163 # Escape and replace whitespace with "+"
164 $name = encode $charset, $name if $charset;
165 $name = url_escape $name, '^*\-.0-9A-Z_a-z';
166 $value = encode $charset, $value if $charset;
167 $value = url_escape $value, '^*\-.0-9A-Z_a-z';
168 s/\%20/\+/g for $name, $value;
169
170 push @pairs, "$name=$value";
171 }
172
173 return join '&', @pairs;
174}
175
17614µs1;
177
178=encoding utf8
179
180=head1 NAME
181
182Mojo::Parameters - Parameters
183
184=head1 SYNOPSIS
185
186 use Mojo::Parameters;
187
188 # Parse
189 my $params = Mojo::Parameters->new('foo=bar&baz=23');
190 say $params->param('baz');
191
192 # Build
193 my $params = Mojo::Parameters->new(foo => 'bar', baz => 23);
194 push @$params, i => '♥ mojolicious';
195 say "$params";
196
197=head1 DESCRIPTION
198
199L<Mojo::Parameters> is a container for form parameters used by L<Mojo::URL>, based on L<RFC
2003986|https://tools.ietf.org/html/rfc3986> and the L<HTML Living Standard|https://html.spec.whatwg.org>.
201
202=head1 ATTRIBUTES
203
204L<Mojo::Parameters> implements the following attributes.
205
206=head2 charset
207
208 my $charset = $params->charset;
209 $params = $params->charset('UTF-8');
210
211Charset used for encoding and decoding parameters, defaults to C<UTF-8>.
212
213 # Disable encoding and decoding
214 $params->charset(undef);
215
216=head1 METHODS
217
218L<Mojo::Parameters> inherits all methods from L<Mojo::Base> and implements the following new ones.
219
220=head2 append
221
222 $params = $params->append(foo => 'ba&r');
223 $params = $params->append(foo => ['ba&r', 'baz']);
224 $params = $params->append(foo => ['bar', 'baz'], bar => 23);
225 $params = $params->append(Mojo::Parameters->new);
226
227Append parameters. Note that this method will normalize the parameters.
228
229 # "foo=bar&foo=baz"
230 Mojo::Parameters->new('foo=bar')->append(Mojo::Parameters->new('foo=baz'));
231
232 # "foo=bar&foo=baz"
233 Mojo::Parameters->new('foo=bar')->append(foo => 'baz');
234
235 # "foo=bar&foo=baz&foo=yada"
236 Mojo::Parameters->new('foo=bar')->append(foo => ['baz', 'yada']);
237
238 # "foo=bar&foo=baz&foo=yada&bar=23"
239 Mojo::Parameters->new('foo=bar')->append(foo => ['baz', 'yada'], bar => 23);
240
241=head2 clone
242
243 my $params2 = $params->clone;
244
245Return a new L<Mojo::Parameters> object cloned from these parameters.
246
247=head2 every_param
248
249 my $values = $params->every_param('foo');
250
251Similar to L</"param">, but returns all values sharing the same name as an array reference. Note that this method will
252normalize the parameters.
253
254 # Get first value
255 say $params->every_param('foo')->[0];
256
257=head2 merge
258
259 $params = $params->merge(foo => 'ba&r');
260 $params = $params->merge(foo => ['ba&r', 'baz']);
261 $params = $params->merge(foo => ['bar', 'baz'], bar => 23);
262 $params = $params->merge(Mojo::Parameters->new);
263
264Merge parameters. Note that this method will normalize the parameters.
265
266 # "foo=baz"
267 Mojo::Parameters->new('foo=bar')->merge(Mojo::Parameters->new('foo=baz'));
268
269 # "yada=yada&foo=baz"
270 Mojo::Parameters->new('foo=bar&yada=yada')->merge(foo => 'baz');
271
272 # "yada=yada"
273 Mojo::Parameters->new('foo=bar&yada=yada')->merge(foo => undef);
274
275=head2 names
276
277 my $names = $params->names;
278
279Return an array reference with all parameter names.
280
281 # Names of all parameters
282 say for @{$params->names};
283
284=head2 new
285
286 my $params = Mojo::Parameters->new;
287 my $params = Mojo::Parameters->new('foo=b%3Bar&baz=23');
288 my $params = Mojo::Parameters->new(foo => 'b&ar');
289 my $params = Mojo::Parameters->new(foo => ['ba&r', 'baz']);
290 my $params = Mojo::Parameters->new(foo => ['bar', 'baz'], bar => 23);
291
292Construct a new L<Mojo::Parameters> object and L</"parse"> parameters if necessary.
293
294=head2 pairs
295
296 my $array = $params->pairs;
297 $params = $params->pairs([foo => 'b&ar', baz => 23]);
298
299Parsed parameter pairs. Note that this method will normalize the parameters.
300
301 # Remove all parameters
302 $params->pairs([]);
303
304=head2 param
305
306 my $value = $params->param('foo');
307 $params = $params->param(foo => 'ba&r');
308 $params = $params->param(foo => qw(ba&r baz));
309 $params = $params->param(foo => ['ba;r', 'baz']);
310
311Access parameter values. If there are multiple values sharing the same name, and you want to access more than just the
312last one, you can use L</"every_param">. Note that this method will normalize the parameters.
313
314=head2 parse
315
316 $params = $params->parse('foo=b%3Bar&baz=23');
317
318Parse parameters.
319
320=head2 remove
321
322 $params = $params->remove('foo');
323
324Remove parameters. Note that this method will normalize the parameters.
325
326 # "bar=yada"
327 Mojo::Parameters->new('foo=bar&foo=baz&bar=yada')->remove('foo');
328
329=head2 to_hash
330
331 my $hash = $params->to_hash;
332
333Turn parameters into a hash reference. Note that this method will normalize the parameters.
334
335 # "baz"
336 Mojo::Parameters->new('foo=bar&foo=baz')->to_hash->{foo}[1];
337
338=head2 to_string
339
340 my $str = $params->to_string;
341
342Turn parameters into a string.
343
344 # "foo=bar&baz=23"
345 Mojo::Parameters->new->pairs([foo => 'bar', baz => 23])->to_string;
346
347=head1 OPERATORS
348
349L<Mojo::Parameters> overloads the following operators.
350
351=head2 array
352
353 my @pairs = @$params;
354
355Alias for L</"pairs">. Note that this will normalize the parameters.
356
357 say $params->[0];
358 say for @$params;
359
360=head2 bool
361
362 my $bool = !!$params;
363
364Always true.
365
366=head2 stringify
367
368 my $str = "$params";
369
370Alias for L</"to_string">.
371
372=head1 SEE ALSO
373
374L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
375
376=cut