| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Mojo/Parameters.pm |
| Statements | Executed 5736249 statements in 4.96s |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 263355 | 2 | 1 | 1.53s | 2.67s | Mojo::Parameters::clone |
| 256012 | 2 | 1 | 1.28s | 1.94s | Mojo::Parameters::to_string |
| 309982 | 2 | 2 | 658ms | 958ms | Mojo::Parameters::new |
| 519367 | 2 | 1 | 653ms | 653ms | Mojo::Parameters::pairs |
| 488601 | 2 | 1 | 319ms | 319ms | Mojo::Parameters::__ANON__[:3] |
| 1 | 1 | 1 | 32µs | 206µs | Mojo::Parameters::BEGIN@2 |
| 1 | 1 | 1 | 12µs | 42µs | Mojo::Parameters::BEGIN@3 |
| 1 | 1 | 1 | 7µs | 145µs | Mojo::Parameters::BEGIN@5 |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::append |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::every_param |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::merge |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::names |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::param |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::parse |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::remove |
| 0 | 0 | 0 | 0s | 0s | Mojo::Parameters::to_hash |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Mojo::Parameters; | ||||
| 2 | 2 | 122µs | 2 | 380µ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 # spent 206µs making 1 call to Mojo::Parameters::BEGIN@2
# spent 174µs making 1 call to Mojo::Base::import |
| 3 | 488603 | 832ms | 2 | 72µ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 # spent 42µs making 1 call to Mojo::Parameters::BEGIN@3
# spent 30µs making 1 call to overload::import |
| 4 | |||||
| 5 | 2 | 1.70ms | 2 | 283µ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 # spent 145µs making 1 call to Mojo::Parameters::BEGIN@5
# spent 138µs making 1 call to Exporter::import |
| 6 | |||||
| 7 | 1 | 3µs | 1 | 61µs | has charset => 'UTF-8'; # spent 61µ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 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 | ||||
| 27 | 263355 | 38.2ms | my $self = shift; | ||
| 28 | |||||
| 29 | 263355 | 217ms | 263355 | 800ms | my $clone = $self->new; # spent 800ms making 263355 calls to Mojo::Parameters::new, avg 3µs/call |
| 30 | 263355 | 235ms | if (exists $self->{charset}) { $clone->{charset} = $self->{charset} } | ||
| 31 | 263355 | 129ms | if (defined $self->{string}) { $clone->{string} = $self->{string} } | ||
| 32 | 263355 | 341ms | 263355 | 340ms | else { $clone->{pairs} = [@{$self->pairs}] } # spent 340ms making 263355 calls to Mojo::Parameters::pairs, avg 1µs/call |
| 33 | |||||
| 34 | 263355 | 418ms | 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 | 309982 | 615ms | 309982 | 300ms | # 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 # spent 300ms making 309982 calls to Mojo::Base::new, avg 967ns/call |
| 64 | |||||
| 65 | sub pairs { | ||||
| 66 | 519367 | 70.3ms | my $self = shift; | ||
| 67 | |||||
| 68 | # Replace parameters | ||||
| 69 | 519367 | 68.3ms | if (@_) { | ||
| 70 | $self->{pairs} = shift; | ||||
| 71 | delete $self->{string}; | ||||
| 72 | return $self; | ||||
| 73 | } | ||||
| 74 | |||||
| 75 | # Parse string | ||||
| 76 | 519367 | 152ms | 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 | 519367 | 757ms | 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 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 | ||||
| 147 | 256012 | 37.7ms | my $self = shift; | ||
| 148 | |||||
| 149 | # String (RFC 3986) | ||||
| 150 | 256012 | 267ms | 256012 | 350ms | my $charset = $self->charset; # spent 350ms making 256012 calls to Mojo::Parameters::charset, avg 1µs/call |
| 151 | 256012 | 111ms | 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 | 256012 | 193ms | 256012 | 313ms | my $pairs = $self->pairs; # spent 313ms making 256012 calls to Mojo::Parameters::pairs, avg 1µs/call |
| 158 | 256012 | 482ms | 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 |