Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
parameters, uploads and cookies without wantarray
  • Loading branch information
kraih committed May 25, 2014
1 parent c9b5474 commit f15ae3a
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 85 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -5,6 +5,7 @@
with user expectations.
- Changed lock and unlock callbacks in Mojo::IOLoop to not receive an
invocant.
- Changed Mojo::Collection to stringify elements with $".
- Removed deprecated support for "X-Forwarded-HTTPS".
- Removed generate_port method from Mojo::IOLoop.
- Removed format method from Mojo::Log.
Expand Down
4 changes: 2 additions & 2 deletions lib/Mojo/Collection.pm
@@ -1,6 +1,6 @@
package Mojo::Collection;
use Mojo::Base -strict;
use overload bool => sub {1}, '""' => sub { shift->join("\n") }, fallback => 1;
use overload bool => sub {1}, '""' => sub { shift->join($") }, fallback => 1;

use Carp 'croak';
use Exporter 'import';
Expand Down Expand Up @@ -319,7 +319,7 @@ Always true.
my $str = "$collection";
Stringify elements in collection and L</"join"> them with newlines.
Stringify elements in collection and L</"join"> them with C<$">.
=head1 SEE ALSO
Expand Down
28 changes: 14 additions & 14 deletions lib/Mojo/Message.pm
Expand Up @@ -3,6 +3,7 @@ use Mojo::Base 'Mojo::EventEmitter';

use Carp 'croak';
use Mojo::Asset::Memory;
use Mojo::Collection;
use Mojo::Content::Single;
use Mojo::DOM;
use Mojo::JSON 'j';
Expand Down Expand Up @@ -248,8 +249,8 @@ sub _cache {
push @{$self->{$method}{$_->name}}, $_ for @{$self->$method};
}

return unless my $objects = $self->{$method}{$name};
return wantarray ? @$objects : $objects->[0];
my $objects = $self->{$method}{$name};
return Mojo::Collection->new(defined $objects ? @$objects : ());
}

sub _limit {
Expand Down Expand Up @@ -459,15 +460,15 @@ Render start line.
=head2 cookie
my $cookie = $msg->cookie('foo');
my @cookies = $msg->cookie('foo');
my $collection = $msg->cookie('foo');
Access message cookies, usually L<Mojo::Cookie::Request> or
L<Mojo::Cookie::Response> objects. Note that this method caches all data, so
it should not be called before all headers have been received.
Access message cookies, usually a L<Mojo::Collection> of
L<Mojo::Cookie::Request> or L<Mojo::Cookie::Response> objects. Note that this
method caches all data, so it should not be called before all headers have
been received.
# Get cookie value
say $msg->cookie('foo')->value;
say $msg->cookie('foo')->first->value;
=head2 cookies
Expand Down Expand Up @@ -621,15 +622,14 @@ Render whole message.
=head2 upload
my $upload = $msg->upload('foo');
my @uploads = $msg->upload('foo');
my $collection = $msg->upload('foo');
Access C<multipart/form-data> file uploads, usually L<Mojo::Upload> objects.
Note that this method caches all data, so it should not be called before the
entire message body has been received.
Access C<multipart/form-data> file uploads, usually a L<Mojo::Collection> of
L<Mojo::Upload> objects. Note that this method caches all data, so it should
not be called before the entire message body has been received.
# Get content of uploaded file
say $msg->upload('foo')->asset->slurp;
say $msg->upload('foo')->first->asset->slurp;
=head2 uploads
Expand Down
28 changes: 13 additions & 15 deletions lib/Mojo/Parameters.pm
Expand Up @@ -6,6 +6,7 @@ use overload
'""' => sub { shift->to_string },
fallback => 1;

use Mojo::Collection;
use Mojo::Util qw(decode encode url_escape url_unescape);

has charset => 'UTF-8';
Expand Down Expand Up @@ -53,7 +54,8 @@ sub param {
return sort keys %{$self->to_hash} unless $name;

# Multiple names
return map { scalar $self->param($_) } @$name if ref $name eq 'ARRAY';
return Mojo::Collection->new(map { $self->param($_) } @$name)
if ref $name eq 'ARRAY';

# Replace values
$self->remove($name) if defined $_[0];
Expand All @@ -66,7 +68,7 @@ sub param {
push @values, $params->[$i + 1] if $params->[$i] eq $name;
}

return wantarray ? @values : $values[0];
return Mojo::Collection->new(@values);
}

sub params {
Expand Down Expand Up @@ -268,19 +270,15 @@ necessary.
=head2 param
my @names = $params->param;
my $foo = $params->param('foo');
my @foo = $params->param('foo');
my ($foo, $bar) = $params->param(['foo', 'bar']);
$params = $params->param(foo => 'ba&r');
$params = $params->param(foo => qw(ba&r baz));
$params = $params->param(foo => ['ba;r', 'baz']);
Check and replace parameter value. Be aware that if you request a parameter by
name in scalar context, you will receive only the I<first> value for that
parameter, if there are multiple values for that name. In list context you
will receive I<all> of the values for that name. Note that this method will
normalize the parameters.
my @names = $params->param;
my $collection = $params->param('foo');
my $collection = $params->param(['foo', 'bar']);
$params = $params->param(foo => 'ba&r');
$params = $params->param(foo => qw(ba&r baz));
$params = $params->param(foo => ['ba;r', 'baz']);
Check and replace parameter value. Note that this method will normalize the
parameters.
=head2 params
Expand Down
49 changes: 17 additions & 32 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -4,6 +4,7 @@ use Mojo::Base -base;
# No imports, for security reasons!
use Carp ();
use Mojo::ByteStream;
use Mojo::Collection;
use Mojo::Exception;
use Mojo::Transaction::HTTP;
use Mojo::URL;
Expand Down Expand Up @@ -55,9 +56,7 @@ sub cookie {
}

# Request cookies
return map { $_->value } $self->req->cookie($name) if wantarray;
return undef unless my $cookie = $self->req->cookie($name);
return $cookie->value;
return $self->req->cookie($name)->map(sub { $_->value });
}

sub finish {
Expand Down Expand Up @@ -101,7 +100,8 @@ sub param {
my ($self, $name) = (shift, shift);

# Multiple names
return map { scalar $self->param($_) } @$name if ref $name eq 'ARRAY';
return Mojo::Collection->new(map { $self->param($_) } @$name)
if ref $name eq 'ARRAY';

# List names
my $captures = $self->stash->{'mojo.captures'} ||= {};
Expand All @@ -122,7 +122,7 @@ sub param {

# Captured unreserved values
if (!$RESERVED{$name} && defined(my $value = $captures->{$name})) {
return ref $value eq 'ARRAY' ? wantarray ? @$value : $$value[0] : $value;
return Mojo::Collection->new(ref $value eq 'ARRAY' ? @$value : $value);
}

# Uploads
Expand Down Expand Up @@ -510,10 +510,9 @@ Continue dispatch chain with L<Mojolicious::Routes/"continue">.
=head2 cookie
my $value = $c->cookie('foo');
my @values = $c->cookie('foo');
$c = $c->cookie(foo => 'bar');
$c = $c->cookie(foo => 'bar', {path => '/'});
my $collection = $c->cookie('foo');
$c = $c->cookie(foo => 'bar');
$c = $c->cookie(foo => 'bar', {path => '/'});
Access request cookie values and create new response cookies.
Expand Down Expand Up @@ -578,31 +577,17 @@ status.
=head2 param
my @names = $c->param;
my $foo = $c->param('foo');
my @foo = $c->param('foo');
my ($foo, $bar) = $c->param(['foo', 'bar']);
$c = $c->param(foo => 'ba;r');
$c = $c->param(foo => qw(ba;r baz));
$c = $c->param(foo => ['ba;r', 'baz']);
my @names = $c->param;
my $collection = $c->param('foo');
my $collection = $c->param(['foo', 'bar']);
$c = $c->param(foo => 'ba;r');
$c = $c->param(foo => qw(ba;r baz));
$c = $c->param(foo => ['ba;r', 'baz']);
Access route placeholder values that are not reserved stash values, file
uploads and C<GET>/C<POST> parameters, in that order. Note that this method is
context sensitive in some cases and therefore needs to be used with care,
there can always be multiple values, which might have unexpected consequences.
Parts of the request body need to be loaded into memory to parse C<POST>
parameters, so you have to make sure it is not excessively large, there's a
10MB limit by default.
# List context is ambiguous and should be avoided, you can get multiple
# values returned for a query string like "?foo=bar&foo=baz&foo=yada"
my $hash = {foo => $self->param('foo')};
# Better enforce scalar context
my $hash = {foo => scalar $self->param('foo')};
# The multi-name form can also be used to enforce scalar context
my $hash = {foo => $self->param(['foo'])};
uploads and C<GET>/C<POST> parameters, in that order. Parts of the request
body need to be loaded into memory to parse C<POST> parameters, so you have to
make sure it is not excessively large, there's a 10MB limit by default.
For more control you can also access request information directly.
Expand Down
14 changes: 7 additions & 7 deletions lib/Mojolicious/Validator/Validation.pm
Expand Up @@ -2,6 +2,7 @@ package Mojolicious::Validator::Validation;
use Mojo::Base -base;

use Carp 'croak';
use Mojo::Collection;
use Scalar::Util 'blessed';

has [qw(csrf_token topic validator)];
Expand Down Expand Up @@ -72,14 +73,14 @@ sub param {
my ($self, $name) = @_;

# Multiple names
return map { scalar $self->param($_) } @$name if ref $name eq 'ARRAY';
return Mojo::Collection->new(map { $self->param($_) } @$name)
if ref $name eq 'ARRAY';

# List names
return sort keys %{$self->output} unless defined $name;

my $value = $self->output->{$name};
my @values = ref $value eq 'ARRAY' ? @$value : ($value);
return wantarray ? @values : $values[0];
return Mojo::Collection->new(ref $value eq 'ARRAY' ? @$value : ($value));
}

sub required {
Expand Down Expand Up @@ -209,10 +210,9 @@ Change validation L</"topic">.
=head2 param
my @names = $validation->param;
my $foo = $validation->param('foo');
my @foo = $validation->param('foo');
my ($foo, $bar) = $validation->param(['foo', 'bar']);
my @names = $validation->param;
my $collection = $validation->param('foo');
my $collection = $validation->param(['foo', 'bar']);
Access validated parameters, similar to L<Mojolicious::Controller/"param">.
Expand Down
10 changes: 5 additions & 5 deletions t/mojo/collection.t
Expand Up @@ -76,7 +76,7 @@ is $collection->join('---'), '1---2---3', 'right result';
is $collection->join("\n"), "1\n2\n3", 'right result';
is $collection->join('/')->url_escape, '1%2F2%2F3', 'right result';
$collection = c(c(1, 2, 3), c(3, 2, 1));
is $collection->join(''), "1\n2\n33\n2\n1", 'right result';
is $collection->join(''), '1 2 33 2 1', 'right result';

# map
$collection = c(1, 2, 3);
Expand Down Expand Up @@ -138,11 +138,11 @@ is_deeply [$collection->slice(6 .. 9)->each], [7, 10, 9, 8], 'right result';

# pluck
$collection = c(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9));
is $collection->pluck('reverse'), "3\n2\n1\n6\n5\n4\n9\n8\n7", 'right result';
is $collection->pluck(join => '-'), "1-2-3\n4-5-6\n7-8-9", 'right result';
is $collection->pluck('reverse'), '3 2 1 6 5 4 9 8 7', 'right result';
is $collection->pluck(join => '-'), '1-2-3 4-5-6 7-8-9', 'right result';
$collection = c(b('one'), b('two'), b('three'));
is $collection->camelize, "One\nTwo\nThree", 'right result';
is $collection->url_escape('^netwhr')->reverse, "%54hree\n%54w%6F\n%4Fne",
is $collection->camelize, 'One Two Three', 'right result';
is $collection->url_escape('^netwhr')->reverse, '%54hree %54w%6F %4Fne',
'right result';

# uniq
Expand Down
10 changes: 4 additions & 6 deletions t/mojo/dom.t
Expand Up @@ -1425,8 +1425,8 @@ is $dom->find('table > colgroup > col')->[2]->attr->{id}, 'bar',
'right attribute';
is $dom->at('table > thead > tr > th')->text, 'A', 'right text';
is $dom->find('table > thead > tr > th')->[1]->text, 'D', 'right text';
is $dom->at('table > tbody > tr > td')->text, 'B', 'right text';
is $dom->find('table > tbody > tr > td')->text, "B\nE", 'right text';
is $dom->at('table > tbody > tr > td')->text, 'B', 'right text';
is $dom->find('table > tbody > tr > td')->text, 'B E', 'right text';

# Optional "colgroup", "tbody", "tr", "th" and "td" tags
$dom = Mojo::DOM->new->parse(<<EOF);
Expand Down Expand Up @@ -2032,8 +2032,7 @@ is $dom->a->B->c->size, 2, 'right number of elements';
@results = ();
$dom->a->B->c->each(sub { push @results, $_->text });
is_deeply \@results, [qw(bar baz)], 'right results';
is $dom->a->B->c, qq{<c id="three">bar</c>\n<c ID="four">baz</c>},
'right result';
is $dom->a->B->c, '<c id="three">bar</c> <c ID="four">baz</c>', 'right result';
is_deeply [keys %$dom], [], 'root has no attributes';
is $dom->find('#nothing'), '', 'no result';

Expand Down Expand Up @@ -2068,8 +2067,7 @@ is $dom->a->b->c->size, 2, 'right number of elements';
@results = ();
$dom->a->b->c->each(sub { push @results, $_->text });
is_deeply \@results, [qw(bar baz)], 'right results';
is $dom->a->b->c, qq{<c id="three">bar</c>\n<c id="four">baz</c>},
'right result';
is $dom->a->b->c, '<c id="three">bar</c> <c id="four">baz</c>', 'right result';
is_deeply [keys %$dom], [], 'root has no attributes';
is $dom->find('#nothing'), '', 'no result';

Expand Down
8 changes: 4 additions & 4 deletions t/mojolicious/dispatch.t
Expand Up @@ -70,14 +70,14 @@ is_deeply $stash, {a => 1, b => 2}, 'set via hash reference';
is $c->param('foo'), undef, 'no value';
is $c->param(foo => 'works')->param('foo'), 'works', 'right value';
is $c->param(foo => 'too')->param('foo'), 'too', 'right value';
is $c->param(foo => qw(just works))->param('foo'), 'just', 'right value';
is_deeply [$c->param('foo')], [qw(just works)], 'right values';
is $c->param(foo => qw(just works))->param('foo'), 'just works', 'right value';
is_deeply [$c->param('foo')->each], [qw(just works)], 'right values';
is $c->param(foo => undef)->param('foo'), undef, 'no value';
is $c->param(foo => Mojo::Upload->new(name => 'bar'))->param('foo')->name,
'bar', 'right value';
is scalar $c->param(foo => ['ba;r', 'baz'])->param('foo'), 'ba;r',
is scalar $c->param(foo => ['ba;r', 'baz'])->param('foo'), 'ba;r baz',
'right value';
is_deeply [$c->param('foo')], ['ba;r', 'baz'], 'right values';
is_deeply [$c->param('foo')->each], ['ba;r', 'baz'], 'right values';

# Reserved stash values are hidden
$c = Mojolicious::Controller->new;
Expand Down

0 comments on commit f15ae3a

Please sign in to comment.