[Catalyst-commits] r13854 - in trunk/examples/CatalystAdvent/root/2010: . pen

t0m at dev.catalyst.perl.org t0m at dev.catalyst.perl.org
Wed Dec 15 00:43:32 GMT 2010


Author: t0m
Date: 2010-12-15 00:43:32 +0000 (Wed, 15 Dec 2010)
New Revision: 13854

Added:
   trunk/examples/CatalystAdvent/root/2010/14.pod
Removed:
   trunk/examples/CatalystAdvent/root/2010/pen/clousres_in_the_stash.pod
Log:
Make mine live

Copied: trunk/examples/CatalystAdvent/root/2010/14.pod (from rev 13852, trunk/examples/CatalystAdvent/root/2010/pen/clousres_in_the_stash.pod)
===================================================================
--- trunk/examples/CatalystAdvent/root/2010/14.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2010/14.pod	2010-12-15 00:43:32 UTC (rev 13854)
@@ -0,0 +1,142 @@
+=head1 Stuffing your stash with closures
+
+=head2 The stash
+
+Every request in Catalyst has a I<stash>, which is scoped to that request.
+It's accessed with the C<< $c->stash >> accessor inside Catalyst, and made
+available within whatever View you are using in your application.
+
+For the purposes of this article, I'll concentrate on L<Template>, i.e. TT,
+but this technique is widely applicable.
+
+The usual pattern is to stash various data (simple scalars, objects, arrays, etc)
+during the course of your request, and you can then retrieve them (and for more
+complex data, like objects, call methods on them), once inside your template.
+
+=head3 Example of trivial usage
+
+    sub foo : Local {
+        my ($self, $c) = @_;
+        $c->stash( things => $c->model('DB::Things')->search({ bar => $c->request->param('bar') }) );
+    }
+    
+    ....
+    
+    <ul>
+    [% FOREACH thing IN things.all %]
+        <li>[% thing.name %]</li>
+    [% END %]
+    </ul>
+
+=head2 Stashing closures
+
+So, you can stash simple scalars, arrays and hashes (and then iterate through them later),
+objects (which you can then call methods on later), but less obviously, you can stash code
+references, and then call that code later..
+
+=head3 Trivial example
+
+    sub foo : Local {
+        my ($self, $c) = @_;
+        $c->stash( thing => sub { return 'quux' } );
+    }
+    
+    ....
+    
+    [% thing() %]
+    prints:
+    quux
+
+=head2 So what's this useful for?
+
+Well, less trivial cases, of course!!
+
+    $c->stash( uri_for_secure => sub { my $uri = $c->uri_for(@_); $uri->scheme('https'); return $uri } );
+    
+    [% c.uri_for_secure(...your normal params here...) %]
+
+Hey, that's useful, eh?
+
+=head2 Danger Will Robinson!!!
+
+B<THE EXAMPLE ABOVE IS UNSAFE>. It causes circular references!
+
+Closing over C<< $c >> (i.e. making a sub reference that includes C<< $c >> inside it),
+and then putting it into a data structure C<< $c->stash >> which is directly
+connected to C<< $c >>, causes a loop, meaning that perl won't B<ever> de-allocate
+the memory.
+
+If you do this once per request, then your application will quickly run out of memory!!
+
+=head2 ContextClosure
+
+    with 'Catalyst::Component::ContextClosure';
+
+    sub foo : Local {
+        my ($self, $c) = @_;
+        $c->stash(
+            uri_with_secure => $self->make_context_closure(sub {
+                my ($c) = @_;
+                my $uri = $c->uri_for(@_);
+                $uri->scheme('https');
+                return $uri;
+            },
+            $c)
+        );
+    }
+    
+Whilst this looks somewhat more baroqe than the previous version, it won't leak any
+memory, and is tremendously useful.
+
+=head2 Sugar
+
+The latest (0.36) version of L<Catalyst::View::TT> has some syntax sugar to make
+adding closures much easier. You don't get the flexibility of being able to change them
+during the request cycle, but for most cases that isn't needed.
+
+In your view configuration, you declare which methods on your view class will be exposed:
+
+    expose_methods => [qw/uri_for_css/],
+
+and you then implement the method (in your View class), without having to worry
+about circular references through the context object, E.g.
+
+    sub uri_for_css {
+        my ($self, $c, $filename) = @_;
+        # Additional complexity here - this is a trivial example!
+        return $c->uri_for('/static/css/' . $filename);
+    }
+
+=head2 Further thoughts and ideas.
+
+Other great things about a stashed closures is that you can have entirely different implementations
+of them for different parts of your site (without needing to add a method on your MyApp object with
+horrible conditional logic in it).
+
+If you're using Chained dispatch, then you can fill in a default closure at the base of your
+chain (for generic requests), and replace it with more specific versions later in the dispatch cycle
+for more specific / customised parts of your application.
+
+As the closures are code refs, it is in fact entirely possible to further customise them by wrapping
+them inside another code ref which does some further work.
+
+For example (building in the C<ContextClosure> example):
+
+    my $old = $c->stash->{uri_with_secure};
+    $c->stash( uri_with_secure => sub { my $uri = $old->(@_); $uri->path('/sekrit' . $uri->path); return $uri });
+    
+    ....
+    
+    [% uri_with_secure('...') %] => forces https, adds /sekrit to the front of any paths generated by uri_for
+
+=head2 Conclusion
+
+I hope this short article has opened your eyes to the potential useages for closures to clean up
+repeated template logic fragments within your application, and given you some ideas for alternatative
+ways to abstract specific fragments of display logic which don't really belong in your application templates.
+
+=head2 Author
+
+Tomas (t0m) Doran C<< <bobtfish at bobtfish.net> >>.
+
+=cut

Deleted: trunk/examples/CatalystAdvent/root/2010/pen/clousres_in_the_stash.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2010/pen/clousres_in_the_stash.pod	2010-12-15 00:42:53 UTC (rev 13853)
+++ trunk/examples/CatalystAdvent/root/2010/pen/clousres_in_the_stash.pod	2010-12-15 00:43:32 UTC (rev 13854)
@@ -1,142 +0,0 @@
-=head1 Stuffing your stash with closures
-
-=head2 The stash
-
-Every request in Catalyst has a I<stash>, which is scoped to that request.
-It's accessed with the C<< $c->stash >> accessor inside Catalyst, and made
-available within whatever View you are using in your application.
-
-For the purposes of this article, I'll concentrate on L<Template>, i.e. TT,
-but this technique is widely applicable.
-
-The usual pattern is to stash various data (simple scalars, objects, arrays, etc)
-during the course of your request, and you can then retrieve them (and for more
-complex data, like objects, call methods on them), once inside your template.
-
-=head3 Example of trivial usage
-
-    sub foo : Local {
-        my ($self, $c) = @_;
-        $c->stash( things => $c->model('DB::Things')->search({ bar => $c->request->param('bar') }) );
-    }
-    
-    ....
-    
-    <ul>
-    [% FOREACH thing IN things.all %]
-        <li>[% thing.name %]</li>
-    [% END %]
-    </ul>
-
-=head2 Stashing closures
-
-So, you can stash simple scalars, arrays and hashes (and then iterate through them later),
-objects (which you can then call methods on later), but less obviously, you can stash code
-references, and then call that code later..
-
-=head3 Trivial example
-
-    sub foo : Local {
-        my ($self, $c) = @_;
-        $c->stash( thing => sub { return 'quux' } );
-    }
-    
-    ....
-    
-    [% thing() %]
-    prints:
-    quux
-
-=head2 So what's this useful for?
-
-Well, less trivial cases, of course!!
-
-    $c->stash( uri_for_secure => sub { my $uri = $c->uri_for(@_); $uri->scheme('https'); return $uri } );
-    
-    [% c.uri_for_secure(...your normal params here...) %]
-
-Hey, that's useful, eh?
-
-=head2 Danger Will Robinson!!!
-
-B<THE EXAMPLE ABOVE IS UNSAFE>. It causes circular references!
-
-Closing over C<< $c >> (i.e. making a sub reference that includes C<< $c >> inside it),
-and then putting it into a data structure C<< $c->stash >> which is directly
-connected to C<< $c >>, causes a loop, meaning that perl won't B<ever> de-allocate
-the memory.
-
-If you do this once per request, then your application will quickly run out of memory!!
-
-=head2 ContextClosure
-
-    with 'Catalyst::Component::ContextClosure';
-
-    sub foo : Local {
-        my ($self, $c) = @_;
-        $c->stash(
-            uri_with_secure => $self->make_context_closure(sub {
-                my ($c) = @_;
-                my $uri = $c->uri_for(@_);
-                $uri->scheme('https');
-                return $uri;
-            },
-            $c)
-        );
-    }
-    
-Whilst this looks somewhat more baroqe than the previous version, it won't leak any
-memory, and is tremendously useful.
-
-=head2 Sugar
-
-The latest (0.36) version of L<Catalyst::View::TT> has some syntax sugar to make
-adding closures much easier. You don't get the flexibility of being able to change them
-during the request cycle, but for most cases that isn't needed.
-
-In your view configuration, you declare which methods on your view class will be exposed:
-
-    expose_methods => [qw/uri_for_css/],
-
-and you then implement the method (in your View class), without having to worry
-about circular references through the context object, E.g.
-
-    sub uri_for_css {
-        my ($self, $c, $filename) = @_;
-        # Additional complexity here - this is a trivial example!
-        return $c->uri_for('/static/css/' . $filename);
-    }
-
-=head2 Further thoughts and ideas.
-
-Other great things about a stashed closures is that you can have entirely different implementations
-of them for different parts of your site (without needing to add a method on your MyApp object with
-horrible conditional logic in it).
-
-If you're using Chained dispatch, then you can fill in a default closure at the base of your
-chain (for generic requests), and replace it with more specific versions later in the dispatch cycle
-for more specific / customised parts of your application.
-
-As the closures are code refs, it is in fact entirely possible to further customise them by wrapping
-them inside another code ref which does some further work.
-
-For example (building in the C<ContextClosure> example):
-
-    my $old = $c->stash->{uri_with_secure};
-    $c->stash( uri_with_secure => sub { my $uri = $old->(@_); $uri->path('/sekrit' . $uri->path); return $uri });
-    
-    ....
-    
-    [% uri_with_secure('...') %] => forces https, adds /sekrit to the front of any paths generated by uri_for
-
-=head2 Conclusion
-
-I hope this short article has opened your eyes to the potential useages for closures to clean up
-repeated template logic fragments within your application, and given you some ideas for alternatative
-ways to abstract specific fragments of display logic which don't really belong in your application templates.
-
-=head2 Author
-
-Tomas (t0m) Doran C<< <bobtfish at bobtfish.net> >>.
-
-=cut




More information about the Catalyst-commits mailing list