cleaned up stash interface
John Napiorkowski [Mon, 14 Jul 2014 00:47:35 +0000 (20:47 -0400)]
lib/Catalyst.pm
lib/Catalyst/Middleware/Stash.pm

index c409eb0..8e7c4fe 100755 (executable)
@@ -498,15 +498,7 @@ Catalyst).
 
 sub stash {
   my $c = shift;
-  my $stash = Catalyst::Middleware::Stash->get($c->req->env);
-  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};
-    }
-  }
-  return $stash;
+  return Catalyst::Middleware::Stash::get_stash($c->req->env)->(@_);
 }
 
 =head2 $c->error
index 8560828..e8746ad 100644 (file)
@@ -1,24 +1,44 @@
-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 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 generate_stash_closure {
+  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 _init_stash {
   my ($self, $env) = @_;
-  $env->{&PSGI_KEY} = bless +{}, 'Catalyst::Stash';
+  return $env->{PSGI_KEY} ||=
+    generate_stash_closure;
 }
 
-sub get {
-  my ($class, $env) = @_;
-  return $env->{&PSGI_KEY};
+sub stash {
+  my ($host, @args) = @_;
+  return get_stash($host->env)->(@args) if
+    $host->can('env');
 }
 
 sub call {
@@ -37,18 +57,44 @@ We've moved the L<Catalyst> 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<PSGI_KEY> which can be dereferenced with
+key values or nothing to access the underly hashref.
 
-This class defines the following methods
+=head1 SUBROUTINES
+
+This class defines the following subroutines.
 
 =head2 PSGI_KEY
 
 Returns the hash key where we store the stash
 
-=head2 get 
+=head2 get_stash
 
 Get the stash out of the C<$env>
 
+=head2 stash
+
+Exportable subroutine.
+
+Given an object with a method C<env> 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.
+
+    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
+
+=head2 generate_stash_closure
+
+Creates the closure which is stored in the L<PSGI> environment.
+
+=head1 METHODS
+
+This class defines the following methods.
+
 =head2 call
 
 Used by plack to call the middleware