← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 15:57:08 2022
Reported on Wed Dec 14 16:00:31 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm
StatementsExecuted 7315629 statements in 6.06s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
335145211.94s3.28sMojo::Parameters::::cloneMojo::Parameters::clone
327802211.52s2.31sMojo::Parameters::::to_stringMojo::Parameters::to_string
66294721784ms784msMojo::Parameters::::pairsMojo::Parameters::pairs
38177222748ms1.08sMojo::Parameters::::newMojo::Parameters::new
63218121403ms403msMojo::Parameters::::__ANON__[:3]Mojo::Parameters::__ANON__[:3]
11140µs296µsMojo::Parameters::::BEGIN@2Mojo::Parameters::BEGIN@2
11113µs47µsMojo::Parameters::::BEGIN@3Mojo::Parameters::BEGIN@3
1117µs210µ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;
22150µs2552µs
# spent 296µs (40+256) within Mojo::Parameters::BEGIN@2 which was called: # once (40µs+256µs) by Mojo::URL::BEGIN@5 at line 2
use Mojo::Base -base;
# spent 296µs making 1 call to Mojo::Parameters::BEGIN@2 # spent 256µs making 1 call to Mojo::Base::import
36321831.08s281µs
# spent 403ms within Mojo::Parameters::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm:3] which was called 632181 times, avg 637ns/call: # 319284 times (206ms+0s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 644ns/call # 312897 times (197ms+0s) by Mojo::URL::query at line 102 of Mojo/URL.pm, avg 631ns/call # spent 47µs (13+34) within Mojo::Parameters::BEGIN@3 which was called: # once (13µs+34µs) by Mojo::URL::BEGIN@5 at line 3
use overload '@{}' => sub { shift->pairs }, bool => sub {1}, '""' => sub { shift->to_string }, fallback => 1;
# spent 47µs making 1 call to Mojo::Parameters::BEGIN@3 # spent 34µs making 1 call to overload::import
4
522.00ms2413µs
# spent 210µs (7+203) within Mojo::Parameters::BEGIN@5 which was called: # once (7µs+203µs) by Mojo::URL::BEGIN@5 at line 5
use Mojo::Util qw(decode encode url_escape url_unescape);
# spent 210µs making 1 call to Mojo::Parameters::BEGIN@5 # spent 203µs making 1 call to Exporter::import
6
712µs157µshas charset => 'UTF-8';
# spent 57µ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 3.28s (1.94+1.34) within Mojo::Parameters::clone which was called 335145 times, avg 10µs/call: # 319284 times (1.85s+1.28s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 10µs/call # 15861 times (87.8ms+56.7ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 9µs/call
sub clone {
2733514549.4ms my $self = shift;
28
29335145260ms335145930ms my $clone = $self->new;
# spent 930ms making 335145 calls to Mojo::Parameters::new, avg 3µs/call
30335145281ms if (exists $self->{charset}) { $clone->{charset} = $self->{charset} }
31335145149ms if (defined $self->{string}) { $clone->{string} = $self->{string} }
32335145432ms335145405ms else { $clone->{pairs} = [@{$self->pairs}] }
# spent 405ms making 335145 calls to Mojo::Parameters::pairs, avg 1µs/call
33
34335145427ms 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
63381772754ms381772335ms
# spent 1.08s (748ms+335ms) within Mojo::Parameters::new which was called 381772 times, avg 3µs/call: # 335145 times (645ms+285ms) by Mojo::Parameters::clone at line 29, avg 3µs/call # 46627 times (103ms+49.8ms) 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 335ms making 381772 calls to Mojo::Base::new, avg 877ns/call
64
65
# spent 784ms within Mojo::Parameters::pairs which was called 662947 times, avg 1µs/call: # 335145 times (405ms+0s) by Mojo::Parameters::clone at line 32, avg 1µs/call # 327802 times (379ms+0s) by Mojo::Parameters::to_string at line 157, avg 1µs/call
sub pairs {
6666294794.5ms my $self = shift;
67
68 # Replace parameters
6966294783.6ms if (@_) {
70 $self->{pairs} = shift;
71 delete $self->{string};
72 return $self;
73 }
74
75 # Parse string
76662947205ms 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
96662947943ms 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 2.31s (1.52+793ms) within Mojo::Parameters::to_string which was called 327802 times, avg 7µs/call: # 311941 times (1.44s+741ms) by Mojo::URL::path_query at line 92 of Mojo/URL.pm, avg 7µs/call # 15861 times (73.8ms+51.9ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 8µs/call
sub to_string {
14732780250.2ms my $self = shift;
148
149 # String (RFC 3986)
150327802315ms327802414ms my $charset = $self->charset;
# spent 414ms making 327802 calls to Mojo::Parameters::charset, avg 1µs/call
151327802117ms 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)
157327802246ms327802379ms my $pairs = $self->pairs;
# spent 379ms making 327802 calls to Mojo::Parameters::pairs, avg 1µs/call
158327802569ms 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
17613µ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