<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Perlblogs &#187; design</title>
	<atom:link href="http://perlblogs.com/category/design/feed/" rel="self" type="application/rss+xml" />
	<link>http://perlblogs.com</link>
	<description>Posts from selected Perl bloggers</description>
	<lastBuildDate>Mon, 06 Feb 2012 20:47:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Plack::Test and Great Test:: Interfaces</title>
		<link>http://www.modernperlbooks.com/mt/2011/09/placktest-and-great-test-interfaces.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/09/placktest-and-great-test-interfaces.html#comments</comments>
		<pubDate>Wed, 21 Sep 2011 17:48:54 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[plack]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=a3a0c96ac9f43777f065d70779cfebc8</guid>
		<description><![CDATA[Plack is great. Most of it is wonderful. I'm less enamored with the interface of Plack::Test, however. In writing the Little Plack Book, I spent a couple of days writing tests for Plack and applications at the PSGI level. Plack::Test...]]></description>
			<content:encoded><![CDATA[
        <p><a href="http://plackperl.org/">Plack</a> is great. Most of it is wonderful. I'm less enamored with the interface of <a href="http://search.cpan.org/perldoc?Plack::Test">Plack::Test</a>, however.</p>

<p>In writing <a href="http://github.com/chromatic/little_plack_book">the
Little Plack Book</a>, I spent a couple of days writing tests for Plack and
applications at the PSGI level. <code>Plack::Test</code> occupies a strange
level in the ecosystem. It's incredibly useful for what it does in selecting
between a no-HTTP backend or any other PSGI-compatible handler, and it offers
some degree of abstraction for making requests and getting results, but it's
far too low level to write tests for complex applications.</p>

<p>When writing tests for a small <a
href="http://search.cpan.org/perldoc?Dancer">Dancer</a> application, I spent
more time getting the Dancer environment set up well for testing than I did
writing the tests. If I'd used <a
href="http://search.cpan.org/perldoc?Dancer::Test">Dancer::Test</a>, I suspect
I'd have made more progress more quickly.</p>

<p>I've had similar experiences with <a
href="http://catalystframework.org/">Catalyst</a> and <a
href="http://search.cpan.org/perldoc?Catalyst::Test">Catalyst::Test</a>.</p>

<p>None of this surprises me&mdash;Catalyst and Dancer are one layer up the
stack from Plack. Most of the interesting things you can test about a Catalyst
or Dancer or Mojolicious or whatever application are properties expressed at
the framework and application layers, not the plumbing layer of Plack.</p>

<p><code>Plack::Test</code> seems best for testing middleware and other
components which occupy the layer between PSGI and applications. Even so,
something about its interface kept bothering me as I wrote tests and prose
about the tests:</p>

<pre><code>test_psgi $app, sub
{
    my $cb  = shift;

    my $res = $cb-&gt;( GET '/?have=tea;want=tea' );
    ok $res-&gt;is_success, 'Request should succeed when values match';
    is $res-&gt;decoded_content, 'ok',
        '... with descriptive success message';

    ...
};</code></pre>

<p>The pattern of a special test function which takes a block of code is
semi-common in the <code>Test::*</code> world; you can see it in <a
href="http://search.cpan.org/perldoc?Test::Exception">Test::Exception</a> and a
lesser extent in <a
href="http://search.cpan.org/perldoc?Test::Fatal">Test::Fatal</a>. The best
example I've seen of this is <a
href="http://search.cpan.org/perldoc?Test::Routine">Test::Routine</a>, which
uses this block syntax to help organize tests into named groups. A disciplined
tester can use this to great effect to clarify what might otherwise become a
big ball of muddy tests.</p>

<p>I like that <code>Plack::Test</code> does the hard work of redirecting
requests to the app I want to test on whichever backend I want, so that I don't
have to worry about setting up a testing deployment target. That part's great.
The confusing part is:</p>

<pre><code>my $cb  = shift;
my $res = $cb-&gt;( GET '/some_url' );</code></pre>

<p><code>test_psgi</code> takes a PSGI application and an anonymous function as
its parameters, then invokes the anonymous function, passing a callback bound
tothe context of the application. Inside the anonymous function (the block, not
the callback), you invoke the callback and pass an <a
href="http://search.cpan.org/perldoc?HTTP::Request">HTTP::Request</a> object
(constructed manually or with a helper such as <a
href="http://search.cpan.org/perldoc?HTTP::Request::Common">HTTP::Request::Common</a>)
and receive an <a
href="http://search.cpan.org/perldoc?HTTP::Response">HTTP::Response</a>
object.</p>

<p>Put that way, it's a lot more confusing than it is, if you're comfortable
with the idea of first-class functions and closures and semi-fluent interfaces
in Perl 5.</p>

<p>Even so, <code>my $res = <strong>$cb-&gt;(</strong> $req )</code> just looks
weird to me. It sticks out. It's visually different from all of the rest of the
code. Everything else outside the test is the semi-fluent interface of
anonymous subs or boring old method calls on objects.</p>

<p>In a discussion with <a href="http://perlalchemy.blogspot.com/">Zbigniew
Łukasiak</a>, I suggested that I'd want an interface more like:</p>

<pre><code>use Plack::Test;

plack_test 'Test description here' =&gt; sub
{
    my $app = shift;
    my $res = $app-&gt;get( '/', { have =&gt; 'tea', want =&gt; 'tea' } );

    ...
};</code></pre>

<p>You can see the influence of <code>Test::Routine</code>. I don't know
exactly how <code>$app</code> gets into the block, but this gives labeled
subtests and the concomitant organization, it obviates the need to create
<code>HTTP::Request</code> and <code>HTTP::Response</code> objects (or their
<code>Plack::</code> equivalents) manually, and everything in the block uses
visually similar mechanisms.</p>

<p>The only hairy part is figuring out how to connect <code>plack_test</code>
to the app while not multiplying hidden global variables or disallowing
customization and decoration with other middleware. Compatibility with <a
href="http://search.cpan.org/perldoc?Plack::Builder">Plack::Builder</a> is
important, but I don't especially want to pass in <code>$app</code> myself
manually.</p>

<p>Besides, to me the only obvious benefits over <a
href="http://search.cpan.org/perldoc?Test::WWW::Mechanize::PSGI">Test::WWW::Mechanize::PSGI</a>
are the subtest groupings. Mech has a huge advantage of providing many useful
test assertion methods which grovel inside responses so I don't have to.</p>

<p>Maybe this is less my discomfort with one part of the
useful-at-the-appropriate-level <code>Plack::Test</code> and more a plea to
distinguish more clearly between various elements of <code>Test::*</code>
modules, as several distinct categories of behavior exist:</p>

<ul>

<li>Setting up a testing environment</li>

<li>Organizing test assertions</li>

<li>Providing test assertions</li>

</ul>

<p>We did a huge amount of work a long time ago with <a
href="http://search.cpan.org/perldoc?Test::Builder">Test::Builder</a> making
sure that everything which wanted to provide test assertions could interact
nicely, and we succeeded. Maybe it's time to consider ways to enable that
composition at other layers of the <code>Test::*</code> stack.</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/09/21/placktest-and-great-test-interfaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Catalyst Session Flash Methody</title>
		<link>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html#comments</comments>
		<pubDate>Thu, 09 Jun 2011 22:08:32 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false">http://www.modernperlbooks.com/mt/2011/06/making-catalyst-session-flash-methody.html</guid>
		<description><![CDATA[I have a handful of modest Catalyst applications and will undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much is that it's reasonably easy to solve a problem experienced in multiple places, extract that...]]></description>
			<content:encoded><![CDATA[
        <p>I have a handful of modest <a
href="http://catalystframework.org/">Catalyst</a> applications and will
undoubtedly have more. One of the reasons I enjoy working with Perl 5 so much
is that it's reasonably easy to solve a problem experienced in multiple places,
extract that solution, and generalize and publish it for other people. The
modern Perl world only makes that easier with Moose, CPAN, and even Github.</p>

<p>Sometimes that ease moves the problem around, which reinforces the notion
that the only two hard problems in computer science are naming and caching. To
abuse that truism, once I've found a workable solution, the hard part is
figuring out what to call it and how to make it available to other people.</p>

<p>Take the <em>flash</em> feature of Catalyst's <a
href="http://search.cpan.org/perldoc?Catalyst::Plugin::Session">Catalyst::Plugin::Session</a>.
It resembles the stash, in that you can store and retrieve information in and
from the flash, but that data is only available until the first request which
uses it. This is incredibly handy for user notifications, such as "You missed a
required entry field!" or "Your interaction succeeded!", especially when
combined with the <a href="http://wavded.github.com/humane-js/">Humane JS
library</a>.</p>

<p>My controller actions have a pattern:</p>

<pre><code>sub edit :Chained( 'get_widget' ) :PathPart('edit') :Args(0)
{
    my ($self, $c) = @_;

    return unless lc $c-&gt;req-&gt;method eq 'post';

    my $params = $c-&gt;req-&gt;params;
    my $widget   = $c-&gt;stash-&gt;{widget};

    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        push @{ $c->flash->{messages} }, 'Updated widget!';
    }
    catch { push @{ $c->flash->{errors} }, $_ };

    return $c-&gt;res-&gt;redirect(
        $c-&gt;uri_for( $c-&gt;controller( 'Widgets' )
          -&gt;action_for( 'index' ) )
    );
}</code></pre>

<p>Yet every time I write that code, it feels slightly wrong, as if I'm
violating encapsulation by updating the variable <em>behind</em> the flash
directly. It's also prone to typos and has the whiff of violating the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>.</p>

<p>I prefer instead to write:</p>

<pre><code>    try
    {
        $widget-&gt;$_( $params-&gt;{$_} ) for $widget-&gt;editable_fields;
        $widget-&gt;update;
        <strong>$c-&gt;add_message( 'Updated widget!' );</strong>
    }
    catch { <strong>$c-&gt;add_error( $_ )</strong> };</code></pre>

<p>... where my actions don't have to know about the internals of <em>how</em>
the flash stores its data, where I don't have the possibility of stomping all
over the array references accidentally, and where I can replace syntax (the
grotty Perl 5 reference syntax!) with a method which describes my intent.</p>

<p>The simplest way to make this work is:</p>

<pre><code>package Catalyst::Plugin::Session::FlashMethods;
# ABSTRACT: add flash-manipulation methods to Catalyst::Plugin::Session

use parent 'Catalyst::Plugin::Session';

use Modern::Perl;

sub add_message
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{messages} }, @_;
}

sub add_error
{
    my $self = shift;
    push @{ $self-&gt;flash-&gt;{errors} }, @_;
}

1;</code></pre>

<p>... and load it in my applications with:</p>

<pre><code>use Catalyst::Plugin::ConfigLoader;
use Catalyst::Plugin::Static::Simple;
<strong>use Catalyst::Plugin::Session::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    ConfigLoader
    Static::Simple
    <strong>Session::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>This approach has (at least) two problems. First, while I'm happy to make
this code available to other developers, I don't want to add any difficulties
to use other plugins which may themselves extend or modify
<code>Catalyst::Plugin::Session</code>.</p>

<p>Second, this code is awfully specific to my own uses. I believe those uses
could help other people, but why solve a problem so specific when genericity
and wider applicability are possible?</p>

<p>Rephrasing the problem might help.</p>

<p>I have a hash. I want named methods to store application-specific data in
that hash. I would like the ability to customize that set of methods methods
without hard-coding them, so as to produce a component that multiple people can
reuse in multiple applications.</p>

<p>You can see why a big bag of untyped stuff (a hash) is useful.</p>

<p>What I really need is a way to say "My application will use these and only
these specific elements of the flash, so please produce methods for them."
Fortunately, I have one in <a
href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized">MooseX::Role::Parameterized</a>.
The consumer of this code looks like:</p>

<pre><code>package MyApp::Catalyst::Plugin::FlashMethods;
# ABSTRACT: role to add flash-manipulation methods to Catalyst app

use Moose;

extends 'Catalyst::Plugin::Session';
with 'Catalyst::Plugin::Role::FlashMethods'
    =&gt; { flash_elements =&gt; [qw( message error )] };

1;</code></pre>

<p>... and it gets enabled in my Catalyst application with:</p>

<pre><code><strong>use MyApp::Catalyst::Plugin::FlashMethods;</strong>
use Catalyst::Plugin::Session::State::Cookie;
use Catalyst::Plugin::Session::Store::FastMmap;

use Catalyst qw/
    -Debug
    ConfigLoader
    Static::Simple
    <strong>+MyApp::Catalyst::Plugin::FlashMethods</strong>
    Session::State::Cookie
    Session::Store::FastMmap
/;</code></pre>

<p>... which consumes the parametric role:</p>

<pre><code>package Catalyst::Plugin::Role::FlashMethods;

use MooseX::Role::Parameterized;

parameter 'flash_elements', isa =&gt; 'ArrayRef[Str]', required =&gt; 1;

role
{
    my $p = shift;

    for my $element (@{ $p-&gt;flash_elements })
    {
        method "add_${element}" =&gt; sub
        {
            my $self = shift;
            push @{ $self-&gt;flash-&gt;{ $element . 's' } }, @_;
        };
    }
};

1;</code></pre>

<p>This code does have some na&iuml;ve in it. In particular, it ought to use a
smarter pluralization scheme. As well, the interface bothers me in two places.
I'm not sure that the module's name is correct. I also don't particularly like
that using this role means creating a new class of ~10 lines to make the code
available as a Catalyst plugin (though how one might expand Catalyst's
<code>import()</code> to understand how to reify a parametric role given the
appropriate parameters is beyond my language design skills today).</p>

<p>Then again, my ~10 line plugin which consumes this role <em>does</em> work
across my multiple Catalyst applications, at the cost of one more file and nine
more lines of code altogether. The ratio of code per method decreases
substantially with each new method I add, though.</p>

<p>I had originally intended to improve stash handling in this fashion, but but
that's much more work. Neither Catalyst's core nor any other plugin I currently
use rely on the presence of flash, so the scope of this work was much smaller.
Even if they did, this approach does not prevent anything else from poking into
the flash for good or ill.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/06/10/making-catalyst-session-flash-methody-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

