Skip to content

Commit

Permalink
Use Return::MultiLevel to wrap route dispatch.
Browse files Browse the repository at this point in the history
As suggested in PerlDancer#432, use Return::MultiLevel to wrap route dispatch.
Cache the multilevel return coderef in the context for forward/redirect
to use.

Add Return::MultiLevel to prereqs and Scope::Upper to recommends.
  • Loading branch information
veryrusty committed Sep 29, 2013
1 parent 0c6e92d commit a375426
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
3 changes: 2 additions & 1 deletion dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ URI::Escape = 0
parent = 0
Template::Tiny = 0
Class::Load = 0

Return::MultiLevel = 0

[Prereqs / Recommends]
; Serializers
Expand All @@ -94,6 +94,7 @@ Crypt::URandom = 0
; extract pod data from apps
Pod::Simple::Search = 0
Pod::Simple::SimpleTree = 0
Scope::Upper = 0

[Prereqs / Suggests]
; Used by Dancer2::Session::YAML
Expand Down
13 changes: 13 additions & 0 deletions lib/Dancer2/Core/Context.pm
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,17 @@ sub destroy_session {
return;
}


=attr with_return
Used to cache the coderef from L<Return::MultiLevel> within the dispatcher.
=cut

has with_return => (
is => 'rw',
predicate => 1,
clearer => 'clear_with_response',
);

1;
19 changes: 16 additions & 3 deletions lib/Dancer2/Core/Dispatcher.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use Dancer2::Core::Types;
use Dancer2::Core::Context;
use Dancer2::Core::Response;

use Return::MultiLevel qw(with_return);

has apps => (
is => 'rw',
isa => ArrayRef,
Expand Down Expand Up @@ -65,9 +67,20 @@ sub dispatch {

$context->request->_set_route_params($match);

my $response = $self->_dispatch_route($route, $context);

return $response if $response->is_halted;
my $response = with_return {
my ($return) = @_;
# stash the multilevel return coderef in the context
$context->with_return($return) if ! $context->has_with_return;
return $self->_dispatch_route($route, $context);
};
# Ensure we clear the with_return handler
$context->clear_with_response;

# No further processing of this response if its halted
if ( $response->is_halted ) {
$app->context(undef);
return $response;
}

# pass the baton if the response says so...
if ( $response->has_passed ) {
Expand Down

0 comments on commit a375426

Please sign in to comment.