use base 'Plack::Middleware';
use Exporter 'import';
-use Scalar::Util 'blessed';
use Carp 'croak';
our @EXPORT_OK = qw(stash get_stash);
sub PSGI_KEY { 'Catalyst.Stash.v1' };
-sub get_stash { return shift->{PSGI_KEY} }
+sub get_stash {
+ my $env = shift;
+ return $env->{&PSGI_KEY} ||
+ _init_stash_in($env);
+}
-sub generate_stash_closure {
+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 ) {
+ foreach my $key (keys %$new_stash) {
$stash->{$key} = $new_stash->{$key};
}
}
};
}
-sub _init_stash {
- my ($self, $env) = @_;
- return $env->{PSGI_KEY} ||=
- generate_stash_closure;
-}
-
-sub stash {
- my ($host, @args) = @_;
- return get_stash($host->env)->(@args);
+sub _init_stash_in {
+ my ($env) = @_;
+ return $env->{&PSGI_KEY} ||=
+ _create_stash;
}
sub call {
my ($self, $env) = @_;
- $self->_init_stash($env);
+ _init_stash_in($env);
return $self->app->($env);
}
=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</get_stash> or L</stash>.
=head2 get_stash
-Get the stash out of the C<$env>
+Expect: $psgi_env.
+
+Exportable subroutine.
+
+Get the stash out of the C<$env>.
=head2 stash
+Expects: An object that does C<env> and arguments
+
Exportable subroutine.
Given an object with a method C<env> get or set stash values, either
reset for each request (it is not persistent or shared across connected
clients. Stash key / value are stored in memory.
- Catalyst::Middleware::Stash 'stash';
+ use Plack::Request;
+ use Catalyst::Middleware::Stash 'stash';
- $c->stash->{foo} = $bar;
- $c->stash( { moose => 'majestic', qux => 0 } );
- $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
+ 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.
-=head2 generate_stash_closure
+ return [200, ['Content-Type' => 'text/plain'],
+ ["I found $stashed in the stash!"]];
+ };
-Creates the closure which is stored in the L<PSGI> environment.
+If the stash does not yet exist, we initialize one and return that.
=head1 METHODS