| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Mojolicious::Routes::Route; | 
| 2 | 52 |  |  | 52 |  | 789 | use Mojo::Base -base; | 
|  | 52 |  |  |  |  | 155 |  | 
|  | 52 |  |  |  |  | 442 |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 | 52 |  |  | 52 |  | 447 | use Carp qw(croak); | 
|  | 52 |  |  |  |  | 225 |  | 
|  | 52 |  |  |  |  | 3009 |  | 
| 5 | 52 |  |  | 52 |  | 417 | use Mojo::DynamicMethods -dispatch; | 
|  | 52 |  |  |  |  | 164 |  | 
|  | 52 |  |  |  |  | 499 |  | 
| 6 | 52 |  |  | 52 |  | 509 | use Mojo::Util; | 
|  | 52 |  |  |  |  | 191 |  | 
|  | 52 |  |  |  |  | 2466 |  | 
| 7 | 52 |  |  | 52 |  | 26726 | use Mojolicious::Routes::Pattern; | 
|  | 52 |  |  |  |  | 216 |  | 
|  | 52 |  |  |  |  | 489 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | has [qw(inline partial)]; | 
| 10 |  |  |  |  |  |  | has 'children' => sub { [] }; | 
| 11 |  |  |  |  |  |  | has parent     => undef, weak => 1; | 
| 12 |  |  |  |  |  |  | has pattern    => sub { Mojolicious::Routes::Pattern->new }; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | # Reserved stash values | 
| 15 |  |  |  |  |  |  | my %RESERVED = map { $_ => 1 } ( | 
| 16 |  |  |  |  |  |  | qw(action app cb controller data extends format handler inline json layout namespace path status template text), | 
| 17 |  |  |  |  |  |  | qw(variant) | 
| 18 |  |  |  |  |  |  | ); | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | sub BUILD_DYNAMIC { | 
| 21 | 3 |  |  | 3 | 0 | 12 | my ($class, $method, $dyn_methods) = @_; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | return sub { | 
| 24 | 27 |  |  | 27 |  | 58 | my $self    = shift; | 
|  |  |  |  | 27 |  |  |  | 
| 25 | 27 |  |  |  |  | 64 | my $dynamic = $dyn_methods->{$self->root}{$method}; | 
| 26 | 27 | 50 |  |  |  | 140 | return $self->$dynamic(@_) if $dynamic; | 
| 27 | 0 |  |  |  |  | 0 | my $package = ref($self); | 
| 28 | 0 |  |  |  |  | 0 | croak qq{Can't locate object method "$method" via package "$package"}; | 
| 29 | 3 |  |  |  |  | 23 | }; | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | sub add_child { | 
| 33 | 996 |  |  | 996 | 1 | 1988 | my ($self, $route) = @_; | 
| 34 | 996 |  |  |  |  | 1529 | push @{$self->children}, $route->remove->parent($self); | 
|  | 996 |  |  |  |  | 2541 |  | 
| 35 | 996 |  |  |  |  | 2504 | $route->pattern->types($self->root->types); | 
| 36 | 996 |  |  |  |  | 2692 | return $self; | 
| 37 |  |  |  |  |  |  | } | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 550 | 100 |  | 550 | 1 | 3471 | sub any { shift->_generate_route(ref $_[0] eq 'ARRAY' ? shift : [], @_) } | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 2 |  |  | 2 | 1 | 7 | sub delete { shift->_generate_route(DELETE => @_) } | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 14 |  |  | 14 | 1 | 967 | sub find { shift->_index->{shift()} } | 
| 44 |  |  |  |  |  |  |  | 
| 45 | 387 |  |  | 387 | 1 | 1276 | sub get { shift->_generate_route(GET => @_) } | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 1408 |  |  | 1408 | 1 | 3369 | sub has_custom_name { !!shift->{custom} } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub has_websocket { | 
| 50 | 287 |  |  | 287 | 1 | 508 | my $self = shift; | 
| 51 | 287 | 100 |  |  |  | 2244 | return $self->{has_websocket} if exists $self->{has_websocket}; | 
| 52 | 98 |  |  |  |  | 181 | return $self->{has_websocket} = grep { $_->is_websocket } @{$self->_chain}; | 
|  | 243 |  |  |  |  | 545 |  | 
|  | 98 |  |  |  |  | 238 |  | 
| 53 |  |  |  |  |  |  | } | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 17785 | 100 |  | 17785 | 1 | 34354 | sub is_endpoint { $_[0]->inline ? undef : !@{$_[0]->children} } | 
|  | 17109 |  |  |  |  | 33506 |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 | 220 |  |  | 220 | 1 | 1148 | sub is_reserved { !!$RESERVED{$_[1]} } | 
| 58 |  |  |  |  |  |  |  | 
| 59 | 2567 |  |  | 2567 | 1 | 9240 | sub is_websocket { !!shift->{websocket} } | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | sub methods { | 
| 62 | 3796 |  |  | 3796 | 1 | 6891 | my $self = shift; | 
| 63 | 3796 | 100 |  |  |  | 11830 | return $self->{methods} unless @_; | 
| 64 | 983 | 100 |  |  |  | 1537 | my $methods = [map uc($_), @{ref $_[0] ? $_[0] : [@_]}]; | 
|  | 983 |  |  |  |  | 3781 |  | 
| 65 | 983 | 100 |  |  |  | 2683 | $self->{methods} = $methods if @$methods; | 
| 66 | 983 |  |  |  |  | 1631 | return $self; | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | sub name { | 
| 70 | 1695 |  |  | 1695 | 1 | 3013 | my $self = shift; | 
| 71 | 1695 | 100 |  |  |  | 7957 | return $self->{name} unless @_; | 
| 72 | 66 |  |  |  |  | 272 | @$self{qw(name custom)} = (shift, 1); | 
| 73 | 66 |  |  |  |  | 236 | return $self; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 2 |  |  | 2 | 1 | 13 | sub options { shift->_generate_route(OPTIONS => @_) } | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub parse { | 
| 79 | 995 |  |  | 995 | 1 | 1760 | my $self = shift; | 
| 80 | 995 |  | 100 |  |  | 2334 | $self->{name} = $self->pattern->parse(@_)->unparsed // ''; | 
| 81 | 995 |  |  |  |  | 5112 | $self->{name} =~ s/\W+//g; | 
| 82 | 995 |  |  |  |  | 3483 | return $self; | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 3 |  |  | 3 | 1 | 21 | sub patch { shift->_generate_route(PATCH => @_) } | 
| 86 | 23 |  |  | 23 | 1 | 116 | sub post  { shift->_generate_route(POST  => @_) } | 
| 87 | 10 |  |  | 10 | 1 | 53 | sub put   { shift->_generate_route(PUT   => @_) } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub remove { | 
| 90 | 998 |  |  | 998 | 1 | 1832 | my $self = shift; | 
| 91 | 998 | 100 |  |  |  | 2287 | return $self unless my $parent = $self->parent; | 
| 92 | 2 |  |  |  |  | 5 | @{$parent->children} = grep { $_ ne $self } @{$parent->children}; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 4 |  |  |  |  | 14 |  | 
|  | 2 |  |  |  |  | 6 |  | 
| 93 | 2 |  |  |  |  | 5 | return $self->parent(undef); | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | sub render { | 
| 97 | 290 |  |  | 290 | 1 | 620 | my ($self, $values) = @_; | 
| 98 | 290 |  | 100 |  |  | 487 | my $path = join '', map { $_->pattern->render($values, !@{$_->children} && !$_->partial) } @{$self->_chain}; | 
|  | 667 |  |  |  |  | 1523 |  | 
|  | 290 |  |  |  |  | 700 |  | 
| 99 | 290 |  | 100 |  |  | 1553 | return $path || '/'; | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  |  | 
| 102 | 1045 |  |  | 1045 | 1 | 2495 | sub root { shift->_chain->[0] } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | sub requires { | 
| 105 | 3431 |  |  | 3431 | 1 | 5543 | my $self = shift; | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | # Routes with conditions can't be cached | 
| 108 | 3431 | 100 |  |  |  | 10975 | return $self->{requires} unless @_; | 
| 109 | 1001 | 100 |  |  |  | 2392 | my $conditions = ref $_[0] eq 'ARRAY' ? $_[0] : [@_]; | 
| 110 | 1001 | 100 |  |  |  | 3073 | return $self unless @$conditions; | 
| 111 | 21 |  |  |  |  | 63 | $self->{requires} = $conditions; | 
| 112 | 21 |  |  |  |  | 64 | $self->root->cache->max_keys(0); | 
| 113 |  |  |  |  |  |  |  | 
| 114 | 21 |  |  |  |  | 88 | return $self; | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | sub suggested_method { | 
| 118 | 48 |  |  | 48 | 1 | 102 | my $self = shift; | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 48 |  |  |  |  | 80 | my %via; | 
| 121 | 48 |  |  |  |  | 146 | for my $route (@{$self->_chain}) { | 
|  | 48 |  |  |  |  | 716 |  | 
| 122 | 98 | 100 | 100 |  |  | 156 | next unless my @via = @{$route->methods // []}; | 
|  | 98 |  |  |  |  | 225 |  | 
| 123 | 31 | 100 |  |  |  | 162 | %via = map { $_ => 1 } keys %via ? grep { $via{$_} } @via : @via; | 
|  | 46 |  |  |  |  | 193 |  | 
|  | 2 |  |  |  |  | 9 |  | 
| 124 |  |  |  |  |  |  | } | 
| 125 |  |  |  |  |  |  |  | 
| 126 | 48 | 100 | 100 |  |  | 246 | return 'POST' if $via{POST} && !$via{GET}; | 
| 127 | 40 | 100 | 100 |  |  | 263 | return $via{GET} ? 'GET' : (sort keys %via)[0] || 'GET'; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | sub to { | 
| 131 | 1510 |  |  | 1510 | 1 | 2268 | my $self = shift; | 
| 132 |  |  |  |  |  |  |  | 
| 133 | 1510 |  |  |  |  | 2987 | my $pattern = $self->pattern; | 
| 134 | 1510 | 100 |  |  |  | 3239 | return $pattern->defaults unless @_; | 
| 135 | 1508 |  |  |  |  | 3852 | my ($shortcut, %defaults) = Mojo::Util::_options(@_); | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 1508 | 100 |  |  |  | 3390 | if ($shortcut) { | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | # Application | 
| 140 | 379 | 100 | 100 |  |  | 2969 | if (ref $shortcut || $shortcut =~ /^[\w:]+$/) { $defaults{app} = $shortcut } | 
|  | 5 | 50 |  |  |  | 17 |  | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | # Controller and action | 
| 143 |  |  |  |  |  |  | elsif ($shortcut =~ /^([\w\-:]+)?\#(\w+)?$/) { | 
| 144 | 374 | 100 |  |  |  | 1477 | $defaults{controller} = $1 if defined $1; | 
| 145 | 374 | 100 |  |  |  | 1113 | $defaults{action}     = $2 if defined $2; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  |  | 
| 149 | 1508 |  |  |  |  | 3114 | @{$pattern->defaults}{keys %defaults} = values %defaults; | 
|  | 1508 |  |  |  |  | 3213 |  | 
| 150 |  |  |  |  |  |  |  | 
| 151 | 1508 |  |  |  |  | 4088 | return $self; | 
| 152 |  |  |  |  |  |  | } | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | sub to_string { | 
| 155 | 5 |  | 100 | 5 | 1 | 16 | join '', map { $_->pattern->unparsed // '' } @{shift->_chain}; | 
|  | 12 |  |  |  |  | 36 |  | 
|  | 5 |  |  |  |  | 17 |  | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  |  | 
| 158 | 17 |  |  | 17 | 1 | 63 | sub under { shift->_generate_route(under => @_) } | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | sub websocket { | 
| 161 | 35 |  |  | 35 | 1 | 110 | my $route = shift->get(@_); | 
| 162 | 35 |  |  |  |  | 81 | $route->{websocket} = 1; | 
| 163 | 35 |  |  |  |  | 103 | return $route; | 
| 164 |  |  |  |  |  |  | } | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | sub _chain { | 
| 167 | 1486 |  |  | 1486 |  | 3453 | my @chain = (my $parent = shift); | 
| 168 | 1486 |  |  |  |  | 3485 | unshift @chain, $parent while $parent = $parent->parent; | 
| 169 | 1486 |  |  |  |  | 5329 | return \@chain; | 
| 170 |  |  |  |  |  |  | } | 
| 171 |  |  |  |  |  |  |  | 
| 172 |  |  |  |  |  |  | sub _generate_route { | 
| 173 | 994 |  |  | 994 |  | 2486 | my ($self, $methods, @args) = @_; | 
| 174 |  |  |  |  |  |  |  | 
| 175 | 994 |  |  |  |  | 1672 | my (@conditions, @constraints, %defaults, $name, $pattern); | 
| 176 | 994 |  |  |  |  | 2750 | while (defined(my $arg = shift @args)) { | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | # First scalar is the pattern | 
| 179 | 1503 | 100 | 100 |  |  | 7037 | if (!ref $arg && !$pattern) { $pattern = $arg } | 
|  | 943 | 100 | 100 |  |  | 2502 |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | # Scalar | 
| 182 | 16 |  |  |  |  | 57 | elsif (!ref $arg && @args) { push @conditions, $arg, shift @args } | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | # Last scalar is the route name | 
| 185 | 50 |  |  |  |  | 193 | elsif (!ref $arg) { $name = $arg } | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | # Callback | 
| 188 | 298 |  |  |  |  | 1030 | elsif (ref $arg eq 'CODE') { $defaults{cb} = $arg } | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | # Constraints | 
| 191 | 76 |  |  |  |  | 239 | elsif (ref $arg eq 'ARRAY') { push @constraints, @$arg } | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | # Defaults | 
| 194 | 120 |  |  |  |  | 643 | elsif (ref $arg eq 'HASH') { %defaults = (%defaults, %$arg) } | 
| 195 |  |  |  |  |  |  | } | 
| 196 |  |  |  |  |  |  |  | 
| 197 | 994 |  |  |  |  | 2624 | my $route = $self->_route($pattern, @constraints)->requires(\@conditions)->to(\%defaults); | 
| 198 | 994 | 100 |  |  |  | 3665 | $methods eq 'under' ? $route->inline(1) : $route->methods($methods); | 
| 199 |  |  |  |  |  |  |  | 
| 200 | 994 | 100 |  |  |  | 5602 | return defined $name ? $route->name($name) : $route; | 
| 201 |  |  |  |  |  |  | } | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | sub _index { | 
| 204 | 30 |  |  | 30 |  | 73 | my $self = shift; | 
| 205 |  |  |  |  |  |  |  | 
| 206 | 30 |  |  |  |  | 77 | my (%auto, %custom); | 
| 207 | 30 |  |  |  |  | 62 | my @children = (@{$self->children}); | 
|  | 30 |  |  |  |  | 108 |  | 
| 208 | 30 |  |  |  |  | 138 | while (my $child = shift @children) { | 
| 209 | 1294 | 100 | 66 |  |  | 2254 | if   ($child->has_custom_name) { $custom{$child->name} ||= $child } | 
|  | 89 |  |  |  |  | 210 |  | 
| 210 | 1205 |  | 66 |  |  | 2025 | else                           { $auto{$child->name}   ||= $child } | 
| 211 | 1294 |  |  |  |  | 2098 | push @children, @{$child->children}; | 
|  | 1294 |  |  |  |  | 2428 |  | 
| 212 |  |  |  |  |  |  | } | 
| 213 |  |  |  |  |  |  |  | 
| 214 | 30 |  |  |  |  | 981 | return {%auto, %custom}; | 
| 215 |  |  |  |  |  |  | } | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | sub _route { | 
| 218 | 994 |  |  | 994 |  | 1474 | my $self = shift; | 
| 219 |  |  |  |  |  |  |  | 
| 220 | 994 |  |  |  |  | 3104 | my $route       = $self->add_child(__PACKAGE__->new->parse(@_))->children->[-1]; | 
| 221 | 994 |  |  |  |  | 2310 | my $new_pattern = $route->pattern; | 
| 222 | 0 |  |  |  |  | 0 | croak qq{Route pattern "@{[$new_pattern->unparsed]}" contains a reserved stash value} | 
| 223 | 994 | 50 |  |  |  | 1544 | if grep { $self->is_reserved($_) } @{$new_pattern->placeholders}; | 
|  | 103 |  |  |  |  | 386 |  | 
|  | 994 |  |  |  |  | 2169 |  | 
| 224 |  |  |  |  |  |  |  | 
| 225 | 994 |  |  |  |  | 2329 | my $old_pattern = $self->pattern; | 
| 226 | 994 |  |  |  |  | 2271 | my $constraints = $old_pattern->constraints; | 
| 227 | 994 | 100 | 100 |  |  | 2453 | $new_pattern->constraints->{format} //= $constraints->{format} if exists $constraints->{format}; | 
| 228 | 994 |  |  |  |  | 2200 | my $defaults = $old_pattern->defaults; | 
| 229 | 994 | 100 | 66 |  |  | 2261 | $new_pattern->defaults->{format} //= $defaults->{format} if exists $defaults->{format}; | 
| 230 |  |  |  |  |  |  |  | 
| 231 | 994 |  |  |  |  | 2606 | return $route; | 
| 232 |  |  |  |  |  |  | } | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | 1; | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =encoding utf8 | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =head1 NAME | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | Mojolicious::Routes::Route - Route | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | use Mojolicious::Routes::Route; | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | my $r = Mojolicious::Routes::Route->new; | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | L is the route container used by L. | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | =head1 ATTRIBUTES | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | L implements the following attributes. | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | =head2 children | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | my $children = $r->children; | 
| 259 |  |  |  |  |  |  | $r           = $r->children([Mojolicious::Routes::Route->new]); | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | The children of this route, used for nesting routes. | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | =head2 inline | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | my $bool = $r->inline; | 
| 266 |  |  |  |  |  |  | $r       = $r->inline($bool); | 
| 267 |  |  |  |  |  |  |  | 
| 268 |  |  |  |  |  |  | Allow L"under"> semantics for this route. | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | =head2 parent | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | my $parent = $r->parent; | 
| 273 |  |  |  |  |  |  | $r         = $r->parent(Mojolicious::Routes::Route->new); | 
| 274 |  |  |  |  |  |  |  | 
| 275 |  |  |  |  |  |  | The parent of this route, usually a L object. Note that this attribute is weakened. | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | =head2 partial | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | my $bool = $r->partial; | 
| 280 |  |  |  |  |  |  | $r       = $r->partial($bool); | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | Route has no specific end, remaining characters will be captured in C. | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | =head2 pattern | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | my $pattern = $r->pattern; | 
| 287 |  |  |  |  |  |  | $r          = $r->pattern(Mojolicious::Routes::Pattern->new); | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | Pattern for this route, defaults to a L object. | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | =head1 METHODS | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | L inherits all methods from L and implements the following new ones. | 
| 294 |  |  |  |  |  |  |  | 
| 295 |  |  |  |  |  |  | =head2 add_child | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | $r = $r->add_child(Mojolicious::Routes::Route->new); | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | Add a child to this route, it will be automatically removed from its current parent if necessary. | 
| 300 |  |  |  |  |  |  |  | 
| 301 |  |  |  |  |  |  | # Reattach route | 
| 302 |  |  |  |  |  |  | $r->add_child($r->find('foo')); | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | =head2 any | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | my $route = $r->any; | 
| 307 |  |  |  |  |  |  | my $route = $r->any('/:foo'); | 
| 308 |  |  |  |  |  |  | my $route = $r->any('/:foo' => sub ($c) {...}); | 
| 309 |  |  |  |  |  |  | my $route = $r->any('/:foo' => sub ($c) {...} => 'name'); | 
| 310 |  |  |  |  |  |  | my $route = $r->any('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 311 |  |  |  |  |  |  | my $route = $r->any('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 312 |  |  |  |  |  |  | my $route = $r->any('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 313 |  |  |  |  |  |  | my $route = $r->any(['GET', 'POST'] => '/:foo' => sub ($c) {...}); | 
| 314 |  |  |  |  |  |  | my $route = $r->any(['GET', 'POST'] => '/:foo' => [foo => qr/\w+/]); | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | Generate L object matching any of the listed HTTP request methods or all. | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | # Route with pattern and destination | 
| 319 |  |  |  |  |  |  | $r->any('/user')->to('user#whatever'); | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | All arguments are optional, but some have to appear in a certain order, like the two supported array reference values, | 
| 322 |  |  |  |  |  |  | which contain the HTTP methods to match and restrictive placeholders. | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | # Route with HTTP methods, pattern, restrictive placeholders and destination | 
| 325 |  |  |  |  |  |  | $r->any(['DELETE', 'PUT'] => '/:foo' => [foo => qr/\w+/])->to('foo#bar'); | 
| 326 |  |  |  |  |  |  |  | 
| 327 |  |  |  |  |  |  | There are also two supported string values, containing the route pattern and the route name, defaulting to the pattern | 
| 328 |  |  |  |  |  |  | C> and a name based on the pattern. | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | # Route with pattern, name and destination | 
| 331 |  |  |  |  |  |  | $r->any('/:foo' => 'foo_route')->to('foo#bar'); | 
| 332 |  |  |  |  |  |  |  | 
| 333 |  |  |  |  |  |  | An arbitrary number of key/value pairs in between the route pattern and name can be used to specify route conditions. | 
| 334 |  |  |  |  |  |  |  | 
| 335 |  |  |  |  |  |  | # Route with pattern, condition and destination | 
| 336 |  |  |  |  |  |  | $r->any('/' => (agent => qr/Firefox/))->to('foo#bar'); | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | A hash reference is used to specify optional placeholders and default values for the stash. | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | # Route with pattern, optional placeholder and destination | 
| 341 |  |  |  |  |  |  | $r->any('/:foo' => {foo => 'bar'})->to('foo#bar'); | 
| 342 |  |  |  |  |  |  |  | 
| 343 |  |  |  |  |  |  | And a code reference can be used to specify a C value to be merged into the default values for the stash. | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | # Route with pattern and a closure as destination | 
| 346 |  |  |  |  |  |  | $r->any('/:foo' => sub ($c) { | 
| 347 |  |  |  |  |  |  | $c->render(text => 'Hello World!'); | 
| 348 |  |  |  |  |  |  | }); | 
| 349 |  |  |  |  |  |  |  | 
| 350 |  |  |  |  |  |  | See L and L for more information. | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | =head2 delete | 
| 353 |  |  |  |  |  |  |  | 
| 354 |  |  |  |  |  |  | my $route = $r->delete; | 
| 355 |  |  |  |  |  |  | my $route = $r->delete('/:foo'); | 
| 356 |  |  |  |  |  |  | my $route = $r->delete('/:foo' => sub ($c) {...}); | 
| 357 |  |  |  |  |  |  | my $route = $r->delete('/:foo' => sub ($c) {...} => 'name'); | 
| 358 |  |  |  |  |  |  | my $route = $r->delete('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 359 |  |  |  |  |  |  | my $route = $r->delete('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 360 |  |  |  |  |  |  | my $route = $r->delete('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 363 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 364 |  |  |  |  |  |  | L for more information. | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | # Route with destination | 
| 367 |  |  |  |  |  |  | $r->delete('/user')->to('user#remove'); | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | =head2 find | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | my $route = $r->find('foo'); | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | Find child route by name, custom names have precedence over automatically generated ones. | 
| 374 |  |  |  |  |  |  |  | 
| 375 |  |  |  |  |  |  | # Change default parameters of a named route | 
| 376 |  |  |  |  |  |  | $r->find('show_user')->to(foo => 'bar'); | 
| 377 |  |  |  |  |  |  |  | 
| 378 |  |  |  |  |  |  | =head2 get | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | my $route = $r->get; | 
| 381 |  |  |  |  |  |  | my $route = $r->get('/:foo'); | 
| 382 |  |  |  |  |  |  | my $route = $r->get('/:foo' => sub ($c) {...}); | 
| 383 |  |  |  |  |  |  | my $route = $r->get('/:foo' => sub ($c) {...} => 'name'); | 
| 384 |  |  |  |  |  |  | my $route = $r->get('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 385 |  |  |  |  |  |  | my $route = $r->get('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 386 |  |  |  |  |  |  | my $route = $r->get('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 389 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 390 |  |  |  |  |  |  | L for more information. | 
| 391 |  |  |  |  |  |  |  | 
| 392 |  |  |  |  |  |  | # Route with destination | 
| 393 |  |  |  |  |  |  | $r->get('/user')->to('user#show'); | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | =head2 has_custom_name | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | my $bool = $r->has_custom_name; | 
| 398 |  |  |  |  |  |  |  | 
| 399 |  |  |  |  |  |  | Check if this route has a custom name. | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | =head2 has_websocket | 
| 402 |  |  |  |  |  |  |  | 
| 403 |  |  |  |  |  |  | my $bool = $r->has_websocket; | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | Check if this route has a WebSocket ancestor and cache the result for future checks. | 
| 406 |  |  |  |  |  |  |  | 
| 407 |  |  |  |  |  |  | =head2 is_endpoint | 
| 408 |  |  |  |  |  |  |  | 
| 409 |  |  |  |  |  |  | my $bool = $r->is_endpoint; | 
| 410 |  |  |  |  |  |  |  | 
| 411 |  |  |  |  |  |  | Check if this route qualifies as an endpoint. | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | =head2 is_reserved | 
| 414 |  |  |  |  |  |  |  | 
| 415 |  |  |  |  |  |  | my $bool = $r->is_reserved('controller'); | 
| 416 |  |  |  |  |  |  |  | 
| 417 |  |  |  |  |  |  | Check if string is a reserved stash value. | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | =head2 is_websocket | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | my $bool = $r->is_websocket; | 
| 422 |  |  |  |  |  |  |  | 
| 423 |  |  |  |  |  |  | Check if this route is a WebSocket. | 
| 424 |  |  |  |  |  |  |  | 
| 425 |  |  |  |  |  |  | =head2 methods | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | my $methods = $r->methods; | 
| 428 |  |  |  |  |  |  | $r          = $r->methods('GET'); | 
| 429 |  |  |  |  |  |  | $r          = $r->methods('GET', 'POST'); | 
| 430 |  |  |  |  |  |  | $r          = $r->methods(['GET', 'POST']); | 
| 431 |  |  |  |  |  |  |  | 
| 432 |  |  |  |  |  |  | Restrict HTTP methods this route is allowed to handle, defaults to no restrictions. | 
| 433 |  |  |  |  |  |  |  | 
| 434 |  |  |  |  |  |  | # Route with two methods and destination | 
| 435 |  |  |  |  |  |  | $r->any('/foo')->methods('GET', 'POST')->to('foo#bar'); | 
| 436 |  |  |  |  |  |  |  | 
| 437 |  |  |  |  |  |  | =head2 name | 
| 438 |  |  |  |  |  |  |  | 
| 439 |  |  |  |  |  |  | my $name = $r->name; | 
| 440 |  |  |  |  |  |  | $r       = $r->name('foo'); | 
| 441 |  |  |  |  |  |  |  | 
| 442 |  |  |  |  |  |  | The name of this route, defaults to an automatically generated name based on the route pattern. Note that the name | 
| 443 |  |  |  |  |  |  | C is reserved for referring to the current route. | 
| 444 |  |  |  |  |  |  |  | 
| 445 |  |  |  |  |  |  | # Route with destination and custom name | 
| 446 |  |  |  |  |  |  | $r->get('/user')->to('user#show')->name('show_user'); | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  | =head2 options | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | my $route = $r->options; | 
| 451 |  |  |  |  |  |  | my $route = $r->options('/:foo'); | 
| 452 |  |  |  |  |  |  | my $route = $r->options('/:foo' => sub ($c) {...}); | 
| 453 |  |  |  |  |  |  | my $route = $r->options('/:foo' => sub ($c) {...} => 'name'); | 
| 454 |  |  |  |  |  |  | my $route = $r->options('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 455 |  |  |  |  |  |  | my $route = $r->options('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 456 |  |  |  |  |  |  | my $route = $r->options('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 457 |  |  |  |  |  |  |  | 
| 458 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 459 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 460 |  |  |  |  |  |  | L for more information. | 
| 461 |  |  |  |  |  |  |  | 
| 462 |  |  |  |  |  |  | # Route with destination | 
| 463 |  |  |  |  |  |  | $r->options('/user')->to('user#overview'); | 
| 464 |  |  |  |  |  |  |  | 
| 465 |  |  |  |  |  |  | =head2 parse | 
| 466 |  |  |  |  |  |  |  | 
| 467 |  |  |  |  |  |  | $r = $r->parse('/user/:id'); | 
| 468 |  |  |  |  |  |  | $r = $r->parse('/user/:id', id => qr/\d+/); | 
| 469 |  |  |  |  |  |  | $r = $r->parse(format => ['json', 'yaml']); | 
| 470 |  |  |  |  |  |  |  | 
| 471 |  |  |  |  |  |  | Parse pattern. | 
| 472 |  |  |  |  |  |  |  | 
| 473 |  |  |  |  |  |  | =head2 patch | 
| 474 |  |  |  |  |  |  |  | 
| 475 |  |  |  |  |  |  | my $route = $r->patch; | 
| 476 |  |  |  |  |  |  | my $route = $r->patch('/:foo'); | 
| 477 |  |  |  |  |  |  | my $route = $r->patch('/:foo' => sub ($c) {...}); | 
| 478 |  |  |  |  |  |  | my $route = $r->patch('/:foo' => sub ($c) {...} => 'name'); | 
| 479 |  |  |  |  |  |  | my $route = $r->patch('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 480 |  |  |  |  |  |  | my $route = $r->patch('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 481 |  |  |  |  |  |  | my $route = $r->patch('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 482 |  |  |  |  |  |  |  | 
| 483 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 484 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 485 |  |  |  |  |  |  | L for more information. | 
| 486 |  |  |  |  |  |  |  | 
| 487 |  |  |  |  |  |  | # Route with destination | 
| 488 |  |  |  |  |  |  | $r->patch('/user')->to('user#update'); | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | =head2 post | 
| 491 |  |  |  |  |  |  |  | 
| 492 |  |  |  |  |  |  | my $route = $r->post; | 
| 493 |  |  |  |  |  |  | my $route = $r->post('/:foo'); | 
| 494 |  |  |  |  |  |  | my $route = $r->post('/:foo' => sub ($c) {...}); | 
| 495 |  |  |  |  |  |  | my $route = $r->post('/:foo' => sub ($c) {...} => 'name'); | 
| 496 |  |  |  |  |  |  | my $route = $r->post('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 497 |  |  |  |  |  |  | my $route = $r->post('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 498 |  |  |  |  |  |  | my $route = $r->post('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 499 |  |  |  |  |  |  |  | 
| 500 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 501 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 502 |  |  |  |  |  |  | L for more information. | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  | # Route with destination | 
| 505 |  |  |  |  |  |  | $r->post('/user')->to('user#create'); | 
| 506 |  |  |  |  |  |  |  | 
| 507 |  |  |  |  |  |  | =head2 put | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | my $route = $r->put; | 
| 510 |  |  |  |  |  |  | my $route = $r->put('/:foo'); | 
| 511 |  |  |  |  |  |  | my $route = $r->put('/:foo' => sub ($c) {...}); | 
| 512 |  |  |  |  |  |  | my $route = $r->put('/:foo' => sub ($c) {...} => 'name'); | 
| 513 |  |  |  |  |  |  | my $route = $r->put('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 514 |  |  |  |  |  |  | my $route = $r->put('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 515 |  |  |  |  |  |  | my $route = $r->put('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 516 |  |  |  |  |  |  |  | 
| 517 |  |  |  |  |  |  | Generate L object matching only C requests, takes the same arguments as L"any"> | 
| 518 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 519 |  |  |  |  |  |  | L for more information. | 
| 520 |  |  |  |  |  |  |  | 
| 521 |  |  |  |  |  |  | # Route with destination | 
| 522 |  |  |  |  |  |  | $r->put('/user')->to('user#replace'); | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | =head2 remove | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | $r = $r->remove; | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | Remove route from parent. | 
| 529 |  |  |  |  |  |  |  | 
| 530 |  |  |  |  |  |  | # Remove route completely | 
| 531 |  |  |  |  |  |  | $r->find('foo')->remove; | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | # Reattach route to new parent | 
| 534 |  |  |  |  |  |  | $r->any('/foo')->add_child($r->find('bar')->remove); | 
| 535 |  |  |  |  |  |  |  | 
| 536 |  |  |  |  |  |  | =head2 render | 
| 537 |  |  |  |  |  |  |  | 
| 538 |  |  |  |  |  |  | my $path = $r->render({foo => 'bar'}); | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | Render route with parameters into a path. | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | =head2 root | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | my $root = $r->root; | 
| 545 |  |  |  |  |  |  |  | 
| 546 |  |  |  |  |  |  | The L object this route is a descendant of. | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | =head2 requires | 
| 549 |  |  |  |  |  |  |  | 
| 550 |  |  |  |  |  |  | my $requires = $r->requires; | 
| 551 |  |  |  |  |  |  | $r           = $r->requires(foo => 1); | 
| 552 |  |  |  |  |  |  | $r           = $r->requires(foo => 1, bar => {baz => 'yada'}); | 
| 553 |  |  |  |  |  |  | $r           = $r->requires([foo => 1, bar => {baz => 'yada'}]); | 
| 554 |  |  |  |  |  |  |  | 
| 555 |  |  |  |  |  |  | Activate conditions for this route. Note that this automatically disables the routing cache, since conditions are too | 
| 556 |  |  |  |  |  |  | complex for caching. | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  | # Route with condition and destination | 
| 559 |  |  |  |  |  |  | $r->get('/foo')->requires(host => qr/mojolicious\.org/)->to('foo#bar'); | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | =head2 suggested_method | 
| 562 |  |  |  |  |  |  |  | 
| 563 |  |  |  |  |  |  | my $method = $r->suggested_method; | 
| 564 |  |  |  |  |  |  |  | 
| 565 |  |  |  |  |  |  | Suggested HTTP method for reaching this route, C and C are preferred. | 
| 566 |  |  |  |  |  |  |  | 
| 567 |  |  |  |  |  |  | =head2 to | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | my $defaults = $r->to; | 
| 570 |  |  |  |  |  |  | $r           = $r->to(action => 'foo'); | 
| 571 |  |  |  |  |  |  | $r           = $r->to({action => 'foo'}); | 
| 572 |  |  |  |  |  |  | $r           = $r->to('controller#action'); | 
| 573 |  |  |  |  |  |  | $r           = $r->to('controller#action', foo => 'bar'); | 
| 574 |  |  |  |  |  |  | $r           = $r->to('controller#action', {foo => 'bar'}); | 
| 575 |  |  |  |  |  |  | $r           = $r->to(Mojolicious->new); | 
| 576 |  |  |  |  |  |  | $r           = $r->to(Mojolicious->new, foo => 'bar'); | 
| 577 |  |  |  |  |  |  | $r           = $r->to(Mojolicious->new, {foo => 'bar'}); | 
| 578 |  |  |  |  |  |  | $r           = $r->to('MyApp'); | 
| 579 |  |  |  |  |  |  | $r           = $r->to('MyApp', foo => 'bar'); | 
| 580 |  |  |  |  |  |  | $r           = $r->to('MyApp', {foo => 'bar'}); | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | Set default parameters for this route. | 
| 583 |  |  |  |  |  |  |  | 
| 584 |  |  |  |  |  |  | =head2 to_string | 
| 585 |  |  |  |  |  |  |  | 
| 586 |  |  |  |  |  |  | my $str = $r->to_string; | 
| 587 |  |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | Stringify the whole route. | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  | =head2 under | 
| 591 |  |  |  |  |  |  |  | 
| 592 |  |  |  |  |  |  | my $route = $r->under(sub ($c) {...}); | 
| 593 |  |  |  |  |  |  | my $route = $r->under('/:foo' => sub ($c) {...}); | 
| 594 |  |  |  |  |  |  | my $route = $r->under('/:foo' => {foo => 'bar'}); | 
| 595 |  |  |  |  |  |  | my $route = $r->under('/:foo' => [foo => qr/\w+/]); | 
| 596 |  |  |  |  |  |  | my $route = $r->under('/:foo' => (agent => qr/Firefox/)); | 
| 597 |  |  |  |  |  |  | my $route = $r->under([format => ['json', 'yaml']]); | 
| 598 |  |  |  |  |  |  |  | 
| 599 |  |  |  |  |  |  | Generate L object for a nested route with its own intermediate destination, takes the same | 
| 600 |  |  |  |  |  |  | arguments as L"any"> (except for the HTTP methods to match, which are not available). See | 
| 601 |  |  |  |  |  |  | L and L for more information. | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | # Longer version | 
| 604 |  |  |  |  |  |  | $r->any('/:foo' => sub ($c) {...})->inline(1); | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | # Intermediate destination and prefix shared between two routes | 
| 607 |  |  |  |  |  |  | my $auth = $r->under('/user')->to('user#auth'); | 
| 608 |  |  |  |  |  |  | $auth->get('/show')->to('#show'); | 
| 609 |  |  |  |  |  |  | $auth->post('/create')->to('#create'); | 
| 610 |  |  |  |  |  |  |  | 
| 611 |  |  |  |  |  |  | =head2 websocket | 
| 612 |  |  |  |  |  |  |  | 
| 613 |  |  |  |  |  |  | my $route = $r->websocket; | 
| 614 |  |  |  |  |  |  | my $route = $r->websocket('/:foo'); | 
| 615 |  |  |  |  |  |  | my $route = $r->websocket('/:foo' => sub ($c) {...}); | 
| 616 |  |  |  |  |  |  | my $route = $r->websocket('/:foo' => sub ($c) {...} => 'name'); | 
| 617 |  |  |  |  |  |  | my $route = $r->websocket('/:foo' => {foo => 'bar'} => sub ($c) {...}); | 
| 618 |  |  |  |  |  |  | my $route = $r->websocket('/:foo' => [foo => qr/\w+/] => sub ($c) {...}); | 
| 619 |  |  |  |  |  |  | my $route = $r->websocket('/:foo' => (agent => qr/Firefox/) => sub ($c) {...}); | 
| 620 |  |  |  |  |  |  |  | 
| 621 |  |  |  |  |  |  | Generate L object matching only WebSocket handshakes, takes the same arguments as L"any"> | 
| 622 |  |  |  |  |  |  | (except for the HTTP methods to match, which are implied). See L and | 
| 623 |  |  |  |  |  |  | L for more information. | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | # Route with destination | 
| 626 |  |  |  |  |  |  | $r->websocket('/echo')->to('example#echo'); | 
| 627 |  |  |  |  |  |  |  | 
| 628 |  |  |  |  |  |  | =head1 SHORTCUTS | 
| 629 |  |  |  |  |  |  |  | 
| 630 |  |  |  |  |  |  | In addition to the L"ATTRIBUTES"> and L"METHODS"> above you can also call shortcuts provided by L"root"> on | 
| 631 |  |  |  |  |  |  | L objects. | 
| 632 |  |  |  |  |  |  |  | 
| 633 |  |  |  |  |  |  | # Add a "firefox" shortcut | 
| 634 |  |  |  |  |  |  | $r->root->add_shortcut(firefox => sub ($r, $path) { | 
| 635 |  |  |  |  |  |  | $r->get($path, agent => qr/Firefox/); | 
| 636 |  |  |  |  |  |  | }); | 
| 637 |  |  |  |  |  |  |  | 
| 638 |  |  |  |  |  |  | # Use "firefox" shortcut to generate routes | 
| 639 |  |  |  |  |  |  | $r->firefox('/welcome')->to('firefox#welcome'); | 
| 640 |  |  |  |  |  |  | $r->firefox('/bye')->to('firefox#bye'); | 
| 641 |  |  |  |  |  |  |  | 
| 642 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 643 |  |  |  |  |  |  |  | 
| 644 |  |  |  |  |  |  | L, L, L. | 
| 645 |  |  |  |  |  |  |  | 
| 646 |  |  |  |  |  |  | =cut |