Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm |
Statements | Executed 7839995 statements in 5.71s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
377358 | 2 | 1 | 1.93s | 3.27s | clone | Mojo::Parameters::
329583 | 2 | 1 | 1.36s | 2.06s | to_string | Mojo::Parameters::
425519 | 2 | 2 | 744ms | 1.08s | new | Mojo::Parameters::
706941 | 2 | 1 | 720ms | 720ms | pairs | Mojo::Parameters::
674641 | 2 | 1 | 362ms | 362ms | __ANON__[:3] | Mojo::Parameters::
1 | 1 | 1 | 25µs | 268µs | BEGIN@2 | Mojo::Parameters::
1 | 1 | 1 | 11µs | 37µs | BEGIN@3 | Mojo::Parameters::
1 | 1 | 1 | 8µs | 139µs | BEGIN@5 | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | append | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | every_param | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | merge | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | names | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | param | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | parse | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | remove | Mojo::Parameters::
0 | 0 | 0 | 0s | 0s | to_hash | Mojo::Parameters::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Mojo::Parameters; | ||||
2 | 2 | 155µs | 2 | 511µs | # spent 268µs (25+243) within Mojo::Parameters::BEGIN@2 which was called:
# once (25µs+243µs) by Mojo::URL::BEGIN@5 at line 2 # spent 268µs making 1 call to Mojo::Parameters::BEGIN@2
# spent 243µs making 1 call to Mojo::Base::import |
3 | 674643 | 1.00s | 2 | 63µs | # spent 362ms within Mojo::Parameters::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm:3] which was called 674641 times, avg 536ns/call:
# 361497 times (201ms+0s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 557ns/call
# 313144 times (160ms+0s) by Mojo::URL::query at line 102 of Mojo/URL.pm, avg 512ns/call
# spent 37µs (11+26) within Mojo::Parameters::BEGIN@3 which was called:
# once (11µs+26µs) by Mojo::URL::BEGIN@5 at line 3 # spent 37µs making 1 call to Mojo::Parameters::BEGIN@3
# spent 26µs making 1 call to overload::import |
4 | |||||
5 | 2 | 2.11ms | 2 | 270µs | # spent 139µs (8+131) within Mojo::Parameters::BEGIN@5 which was called:
# once (8µs+131µs) by Mojo::URL::BEGIN@5 at line 5 # spent 139µs making 1 call to Mojo::Parameters::BEGIN@5
# spent 131µs making 1 call to Exporter::import |
6 | |||||
7 | 1 | 4µs | 1 | 67µs | has charset => 'UTF-8'; # spent 67µs making 1 call to Mojo::Parameters::has |
8 | |||||
9 | sub 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.27s (1.93+1.33) within Mojo::Parameters::clone which was called 377358 times, avg 9µs/call:
# 361497 times (1.85s+1.28s) by Mojo::URL::clone at line 16 of Mojo/URL.pm, avg 9µs/call
# 15861 times (84.9ms+51.6ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 9µs/call | ||||
27 | 377358 | 49.8ms | my $self = shift; | ||
28 | |||||
29 | 377358 | 253ms | 377358 | 933ms | my $clone = $self->new; # spent 933ms making 377358 calls to Mojo::Parameters::new, avg 2µs/call |
30 | 377358 | 291ms | if (exists $self->{charset}) { $clone->{charset} = $self->{charset} } | ||
31 | 377358 | 153ms | if (defined $self->{string}) { $clone->{string} = $self->{string} } | ||
32 | 377358 | 405ms | 377358 | 400ms | else { $clone->{pairs} = [@{$self->pairs}] } # spent 400ms making 377358 calls to Mojo::Parameters::pairs, avg 1µs/call |
33 | |||||
34 | 377358 | 433ms | return $clone; | ||
35 | } | ||||
36 | |||||
37 | sub 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 | |||||
49 | sub 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 | |||||
61 | sub names { [sort keys %{shift->to_hash}] } | ||||
62 | |||||
63 | 425519 | 756ms | 425519 | 331ms | # spent 1.08s (744ms+331ms) within Mojo::Parameters::new which was called 425519 times, avg 3µs/call:
# 377358 times (649ms+284ms) by Mojo::Parameters::clone at line 29, avg 2µs/call
# 48161 times (95.4ms+47.6ms) by Mojo::URL::query at line 102 of Mojo/URL.pm, avg 3µs/call # spent 331ms making 425519 calls to Mojo::Base::new, avg 779ns/call |
64 | |||||
65 | sub pairs { | ||||
66 | 706941 | 83.2ms | my $self = shift; | ||
67 | |||||
68 | # Replace parameters | ||||
69 | 706941 | 75.5ms | if (@_) { | ||
70 | $self->{pairs} = shift; | ||||
71 | delete $self->{string}; | ||||
72 | return $self; | ||||
73 | } | ||||
74 | |||||
75 | # Parse string | ||||
76 | 706941 | 177ms | 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 | |||||
96 | 706941 | 930ms | return $self->{pairs} //= []; | ||
97 | } | ||||
98 | |||||
99 | sub 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 | |||||
106 | sub 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 | |||||
117 | sub 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 | |||||
125 | sub 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.06s (1.36+706ms) within Mojo::Parameters::to_string which was called 329583 times, avg 6µs/call:
# 313722 times (1.29s+657ms) by Mojo::URL::path_query at line 92 of Mojo/URL.pm, avg 6µs/call
# 15861 times (66.0ms+48.8ms) by Mojo::URL::to_abs at line 143 of Mojo/URL.pm, avg 7µs/call | ||||
147 | 329583 | 47.2ms | my $self = shift; | ||
148 | |||||
149 | # String (RFC 3986) | ||||
150 | 329583 | 288ms | 329583 | 385ms | my $charset = $self->charset; # spent 385ms making 329583 calls to Mojo::Parameters::charset, avg 1µs/call |
151 | 329583 | 106ms | 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) | ||||
157 | 329583 | 204ms | 329583 | 320ms | my $pairs = $self->pairs; # spent 320ms making 329583 calls to Mojo::Parameters::pairs, avg 972ns/call |
158 | 329583 | 460ms | 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 | |||||
176 | 1 | 4µs | 1; | ||
177 | |||||
178 | =encoding utf8 | ||||
179 | |||||
180 | =head1 NAME | ||||
181 | |||||
182 | Mojo::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 | |||||
199 | L<Mojo::Parameters> is a container for form parameters used by L<Mojo::URL>, based on L<RFC | ||||
200 | 3986|https://tools.ietf.org/html/rfc3986> and the L<HTML Living Standard|https://html.spec.whatwg.org>. | ||||
201 | |||||
202 | =head1 ATTRIBUTES | ||||
203 | |||||
204 | L<Mojo::Parameters> implements the following attributes. | ||||
205 | |||||
206 | =head2 charset | ||||
207 | |||||
208 | my $charset = $params->charset; | ||||
209 | $params = $params->charset('UTF-8'); | ||||
210 | |||||
211 | Charset 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 | |||||
218 | L<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 | |||||
227 | Append 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 | |||||
245 | Return a new L<Mojo::Parameters> object cloned from these parameters. | ||||
246 | |||||
247 | =head2 every_param | ||||
248 | |||||
249 | my $values = $params->every_param('foo'); | ||||
250 | |||||
251 | Similar to L</"param">, but returns all values sharing the same name as an array reference. Note that this method will | ||||
252 | normalize 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 | |||||
264 | Merge 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 | |||||
279 | Return 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 | |||||
292 | Construct 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 | |||||
299 | Parsed 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 | |||||
311 | Access parameter values. If there are multiple values sharing the same name, and you want to access more than just the | ||||
312 | last 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 | |||||
318 | Parse parameters. | ||||
319 | |||||
320 | =head2 remove | ||||
321 | |||||
322 | $params = $params->remove('foo'); | ||||
323 | |||||
324 | Remove 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 | |||||
333 | Turn 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 | |||||
342 | Turn 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 | |||||
349 | L<Mojo::Parameters> overloads the following operators. | ||||
350 | |||||
351 | =head2 array | ||||
352 | |||||
353 | my @pairs = @$params; | ||||
354 | |||||
355 | Alias 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 | |||||
364 | Always true. | ||||
365 | |||||
366 | =head2 stringify | ||||
367 | |||||
368 | my $str = "$params"; | ||||
369 | |||||
370 | Alias for L</"to_string">. | ||||
371 | |||||
372 | =head1 SEE ALSO | ||||
373 | |||||
374 | L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>. | ||||
375 | |||||
376 | =cut |