X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FMiddleware%2FStash.pm;h=f874810e6406424dd6e5565f97aeb7df9351ddf9;hp=8560828e4a905141ba2a286d23e46b77b5d8ce47;hb=bde334da382a3d3ac58a63c9061639e712a02e0a;hpb=6561feaea6cb3f0a84e97fc6f2bc55788fe8c393 diff --git a/lib/Catalyst/Middleware/Stash.pm b/lib/Catalyst/Middleware/Stash.pm index 8560828..f874810 100644 --- a/lib/Catalyst/Middleware/Stash.pm +++ b/lib/Catalyst/Middleware/Stash.pm @@ -1,33 +1,53 @@ -package ## Hide from pause - Catalyst::Middleware::Stash; - -# Please don't use this, this is likely to go away before stable version is -# released. Ideally this could be a stand alone distribution. -# - use strict; use warnings; + +package Catalyst::Middleware::Stash; + use base 'Plack::Middleware'; +use Exporter 'import'; +use Carp 'croak'; -sub PSGI_KEY { 'Catalyst.Stash.v1' }; +our @EXPORT_OK = qw(stash get_stash); -sub _init_stash { - my ($self, $env) = @_; - $env->{&PSGI_KEY} = bless +{}, 'Catalyst::Stash'; +sub PSGI_KEY () { 'Catalyst.Stash.v1' } + +sub get_stash { + my $env = shift; + return $env->{+PSGI_KEY} || + croak "You requested a stash, but one does not exist."; } -sub get { - my ($class, $env) = @_; - return $env->{&PSGI_KEY}; +sub stash { + my ($host, @args) = @_; + return get_stash($host->env) + ->(@args); +} + +sub _create_stash { + my $stash = shift || +{}; + return sub { + if(@_) { + my $new_stash = @_ > 1 ? {@_} : $_[0]; + croak('stash takes a hash or hashref') + unless ref $new_stash; + foreach my $key (keys %$new_stash) { + $stash->{$key} = $new_stash->{$key}; + } + } + $stash; + }; } sub call { my ($self, $env) = @_; - $self->_init_stash($env); + my $new_env = +{ %$env }; + my %stash = %{ ($env->{+PSGI_KEY} || sub {})->() || +{} }; + + $env->{+PSGI_KEY} = _create_stash( \%stash ); return $self->app->($env); } -=head1 TITLE +=head1 NAME Catalyst::Middleware::Stash - The Catalyst stash - in middleware @@ -37,17 +57,64 @@ We've moved the L stash to middleware. Please don't use this directly since it is likely to move off the Catalyst namespace into a stand alone distribution -=head1 METHODS +We store a coderef under the C which can be dereferenced with +key values or nothing to access the underlying hashref. + +The stash middleware is designed so that you can 'nest' applications that +use it. If for example you have a L application that is called +by a controller under a parent L application, the child application +will inherit the full stash of the parent BUT any new keys added by the child +will NOT bubble back up to the parent. However, children of children will. + +For more information the current test case t/middleware-stash.t is the best +documentation. + +=head1 SUBROUTINES -This class defines the following methods +This class defines the following subroutines. =head2 PSGI_KEY -Returns the hash key where we store the stash +Returns the hash key where we store the stash. You should not assume +the string value here will never change! Also, its better to use +L or L. -=head2 get +=head2 get_stash + +Expect: $psgi_env. + +Exportable subroutine. + +Get the stash out of the C<$env>. + +=head2 stash + +Expects: An object that does C and arguments + +Exportable subroutine. + +Given an object with a method C get or set stash values, either +as a method or via hashref modification. This stash is automatically +reset for each request (it is not persistent or shared across connected +clients. Stash key / value are stored in memory. + + use Plack::Request; + use Catalyst::Middleware::Stash 'stash'; + + my $app = sub { + my $env = shift; + my $req = Plack::Request->new($env); + my $stashed = $req->stash->{in_the_stash}; # Assume the stash was previously populated. + + return [200, ['Content-Type' => 'text/plain'], + ["I found $stashed in the stash!"]]; + }; + +If the stash does not yet exist, an exception is thrown. + +=head1 METHODS -Get the stash out of the C<$env> +This class defines the following methods. =head2 call