<?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>Fri, 18 May 2012 19:03:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Picking Functional Programming&#8217;s Pockets</title>
		<link>http://www.modernperlbooks.com/mt/2012/04/picking-functional-programmings-pockets.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/04/picking-functional-programmings-pockets.html#comments</comments>
		<pubDate>Mon, 30 Apr 2012 19:49:43 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[functionalprogramming]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[purity]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=4665bcfaeb4de72be73c62ebd1976eb2</guid>
		<description><![CDATA[In all of the debates over whether pair programming is exclusively 100% good or exclusively 100% evil or whether test-driven design is exclusively 100% beneficial or exclusively 100% silly, people sometimes miss the nuances of the polemic &#34;if it's hard...]]></description>
			<content:encoded><![CDATA[
        <p>In all of the debates over whether pair programming is exclusively 100% good
or exclusively 100% evil or whether test-driven design is exclusively 100%
beneficial or exclusively 100% silly, people sometimes miss the nuances of the
polemic "if it's hard to test, it's hard to use".</p>

<p>In practice, that means that good programmers with good taste built from
painful experiences have the ability to write better code if they exercise good
taste when building tests.</p>

<p>(I know, this is the Internet of 21st century culture; the law of the
excluded middle suggests that nuance, like irony, is deader than 19th century
utopian cults. Doesn't mean that 10,000 volts of CPR are <em>always</em>
wasted.)</p>

<p>That's what I had in mind when I wrote <a
href="http://www.modernperlbooks.com/mt/2012/04/mock-objects-despoil-your-tests.html">Mock
Objects Despoil Your Tests</a>. (See also Martin Fowler's <a
href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren't
Stubs</a>.)</p>

<p>The more gyrations your code has to undergo before you're confident that it
does what you intend it to do, no more and no less, the less confidence you
have overall. In highfalutin' architecture astronaut terms, the more tightly coupled your tests are to the internals of your code, the worse your tests are. They could be fragile. They could make too many assumptions. They could be exercising things that no real code would exercise. They could be hard to write and overspecific.</p>

<p>In short, the likelihood that you've built yourself a maintenance burden is
higher when you know far too much about the internals of a thing outside of
that thing, even if the thing on the outside is a test intended to give you
confidence.</p>

<p>(That's why I distrust putting code and tests in the same file, thank you
very much Java. It's too tempting to cheat when the clear lines of demarcation
aren't there.)</p>

<p>I only realized what I've been doing lately when I read Buddy Burden's <a
href="http://blogs.perl.org/users/buddy_burden/2012/04/lazy-cache.html">Lazy ==
Cache?</a>. He describes Moose lazy attributes the way I see them: as a promise
to provide information when you need it. That laziness is a hallmark of
Haskell. If you take laziness as far as Haskell does, you can build amazing
things where things just happen when you need them.</p>

<p>Haskell, of course, goes a long way to encourage you to write programs in a
pure style, where functions don't have side effects. Data comes into a function
and data goes out, and the state of the world stays unchanged. Sure, you can't
write any interesting program without at least performing IO, but Haskell
encourages you to embrace purity as much as possible such that you minimize the
places you update global state.</p>

<p>In my recent code, this has also just sort of happened, even in that code
which isn't Haskell.</p>

<p>Consider an application which tracks daily stock market information, such as
price and market capitalization. Each stock is a row in a table modeled by <a
href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a>. Each stock
has an associated state, like "fetch daily price" or "write yearly free cash
graph" or "invalid name; review".</p>

<p>No one would fault you for updating the stock price, market cap, and state
on a successful fetch from the web service which provides this information.
That's exactly what I used to do.</p>

<p>Now I don't.</p>

<p>I've separated the fetching of data from the parsing of data from the
updating of data. Fetching and updating are solved problems; they happen at the
boundaries of my code and I can only control so much about them. Either the
database works or it doesn't. Either the remote web service is up or it isn't.
(I still test them, but I've isolated them as much as possible.)</p>

<p>The interesting thing is always in the parsing and analysis. This is where
all of the assumptions appear. (Is Berkshire Hathaway's A class
<code>BRK.a</code> or <code>BRK-A</code> or something else? Are abbreviations
acceptable in sector and industry classifications?) This is where I want to
focus my testing&mdash;even my ad hoc testing, when I've found an assumption
but need to research what's gone wrong and why before I can formalize my
solution in test cases and code.</p>

<p>This means, the daily analysis method looks something like:</p>

<pre><code>sub analyze_daily
{
    my ($self, $stock, $updates) = @_;
    my $stats                    = $self-&gt;get_daily_stats_for( $stock-&gt;symbol );

    return unless $stats-&gt;{current_price};
    $updates-&gt;{current_price} = $stats-&gt;{current_price};

    return unless $stats-&gt;{market_capitalization};
    $updates-&gt;{market_capitalization} = $stats-&gt;{market_capitalization};

    $updates-&gt;{PK} = $stock-&gt;symbol;
    return 1;
}</code></pre>

<p>Any code that wants to test this can pass in a hash reference for
<code>$updates</code> and a stock object (or equivalent) in <code>$stock</code>
and test that the results are sane by exploring the hash reference directly,
rather than poking around in <code>$stock</code>.</p>

<p>(The data fetcher itself uses dependency injection and fixture data so that
all expected values are known values and that network errors or transient
failures don't affect this test; obviously other tests must verify that the
remote API behaves as expected. While I could make <code>$stats</code> a
parameter here, I haven't had the need to go that far yet. There's a point
beyond removing dependencies from inside a discrete unit of code makes little
sense.)</p>

<p>This code is also much more reusable; it's trivial to create a <em>bin/</em>
or <em>script/</em> directory full of little utilities which use the same API
as the tests and help me debug or clean up or inspect all of this wonderful
data.</p>

<p>Better yet, I find myself needing fewer tests, because each unit under test
does less and has fewer loops and conditionals and edge cases. The problem
becomes "What's the right fixture data to exercise the interesting behavior of
this code?" My tests care less about managing the state of the objects and
entities under test than they do about the transformations of data.</p>

<p>Perhaps it's not so strange that that's exactly what my programs care
about too.</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/04/30/picking-functional-programmings-pockets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Defending Against Its Dynamic Scope</title>
		<link>http://www.modernperlbooks.com/mt/2012/04/defending-against-its-dynamic-scope.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/04/defending-against-its-dynamic-scope.html#comments</comments>
		<pubDate>Mon, 09 Apr 2012 18:37:06 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=e265d13e3a65e0c61169bf7d14968d95</guid>
		<description><![CDATA[A lot of the advice given in Modern Perl: the Book is advice learned the hard way, whether through making my own mistakes, debugging code written on my teams, or reviewing code written by other people to help novices become...]]></description>
			<content:encoded><![CDATA[
        <p>A lot of the advice given in <a
href="http://onyxneon.com/books/modern_perl">Modern Perl: the Book</a> is
advice learned the hard way, whether through making my own mistakes, debugging
code written on my teams, or reviewing code written by other people to help
novices become better programmers. After a decade-plus of this experience, I
think I've developed a good sense of what people find confusing and what
problems rarely occur in practice.</p>

<p>The pervasive use of global variables? It'll eventually catch up to you.
Variables popping into existence upon use, not declaration? It'll cause
problems far sooner than you ever expect.</p>

<p>Clobbering <code>$_</code> at a distance inside a <code>map</code> block? It happened to me the other day. Yes, it surprised me too.</p>

<p>I've been attaching the Perl search bindings <a
href="http://search.cpan.org/perldoc?Lucy">Lucy</a> to a document processing
engine. As part of the processing stage, my code adds documents to the search
index. The index schema keeps track of specific fields, and it's denormalized
slightly to decouple the document database from the search index. The code to
add a document to the index creates a hash from method calls on each document
object. That's where things started to go wrong:</p>

<pre><code>sub add_entries
{
    my ($self, $entries) = @_;
    my $index            = $self-&gt;index;

    for my $entry (@$entries)
    {
        my $fields =
        {
            <strong>map { $_ =&gt; scalar $entry-&gt;$_() } keys %index_fields</strong>
        };

        $index-&gt;add_doc( $fields );
    }

    $index-&gt;commit;
    $self-&gt;clear_index;
}</code></pre>

<p>I noticed things went wrong when my test bailed out with strange errors.
Lucy was complaining about getting a hash key of <code>''</code>, the empty
string. I was certain that <code>%index_fields</code> was correct.</p>

<p>While most of the methods called are simply accessors for simple object properties, these document objects have a method called <code>short_content()</code>:

<pre><code>sub short_content
{
    my $self    = shift;
    my $meth    = length $self-&gt;content &gt; $MIN_LENGTH ? 'content' : 'summary';
    my $content = $self-&gt;$meth();

    return unless defined $content;

    my $splitter     = Lingua::Sentence-&gt;new( 'en' );
    my $total_length = 0;
    my @sentences;

    for my $sentence ($splitter-&gt;split_array( $content ))
    {
        push @sentences, $sentence;
        $total_length += length $sentence;

        # must be a big mess, if this is true
        return $self-&gt;summary
            if  @sentences    == 1
            and $total_length &gt; $MAX_SANE_LENGTH;
        last if $total_length &gt; 0.65 * $MAX_LENGTH;
    }

    if (@sentences)
    {
        my $text = join ' ', @sentences;
        return $text if length $text &gt; $MAX_SENTENCE_LENGTH && $text =~ /\S/;
    }

    return substr $content, 0, $MAX_SHORT_CONTENT_LENGTH;
}</code></pre>

<p>A document may have a summary. It has content. <code>short_content()</code>
returns a slice of the first significant portion of either, depending on which
exists. While it's not the most detailed portion of the document, it's the
earliest significant portion of the document, and it's demonstrably the best
portion to index as a summary. (Thank you, <a
href="http://voices.yahoo.com/using-inverted-pyramid-write-news-articles-212793.html">inverted
pyramid</a>.)</p>

<p>The rest of this method attempts to break the short content at a sentence
boundary, so as not to cut it off in the middle of a word or thought.</p>

<p>Nothing in that method obviously clobbers <code>$_</code>, but something
called from it apparently does. (I wonder if <a
href="http://search.cpan.org/perldoc?Lingua::Sentence">Lingua::Sentence</a> or
one of its dependencies reads from a file or performs a substitution.)
Regardless, I protected my precious hash key with a little defensive
programming:</p>

<pre><code>        my $fields =
        {
            map { <strong>my $field = $_; $field =&gt; scalar $entry-&gt;$field()</strong> }
                keys %index_fields
        };
</code></pre>

<p>... and all was well.</p>

<p>While this has been a very rare occurrence in 13+ years of Perl 5 programming, the trap is particularly insidious. The more work Perl does within that <code>map</code> block, the greater the potential for action at a distance. Furthermore, the better my abstractions&mdash;the more behavior hidden behind that simple method call&mdash;the greater my exposure to this type of bug.</p>

<p>Throw in things like <a
href="http://www.modernperlbooks.com/mt/2011/08/youre-already-using-dependency-injection.html">dependency
injection</a> and <a
href="http://www.modernperlbooks.com/mt/2012/02/the-memoization-of-lazy-attributes.html">Moose
lazy attributes</a> where you don't have to manage the dependency graph of your
data initialization and flow yourself (generally a good thing) and you can't
tell what's going to happen where or when.</p>

<p>If my instincts are correct, and something reads from a file somewhere such
that only the <em>first</em> call to construct a <code>Lingua::Sentence</code>
object clobbers <code>$_</code>, the point is doubly true.</p>

<p>(Sure, changing <code>map</code> to autolexicalize <code>$_</code> would fix
this problem, but it has backwards compatibility concerns for people who
<em>rely</em> on this action at a distance&mdash;remember, it's only a problem
if you <em>write</em> to <code>$_</code>&mdash;and it's too late to get such a
change into Perl 5.16, even if it were only enabled with <code>use
5.016;</code>. Meanwhile, a variable assignment fixes it for me right now, and
that will have to suffice.)</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/04/09/defending-against-its-dynamic-scope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Memoization of Lazy Attributes</title>
		<link>http://www.modernperlbooks.com/mt/2012/02/the-memoization-of-lazy-attributes.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/02/the-memoization-of-lazy-attributes.html#comments</comments>
		<pubDate>Mon, 27 Feb 2012 18:45:41 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[cpan]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[oop]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=86f465784ea4372fc5c44358736330ad</guid>
		<description><![CDATA[Great software changes the way you use computers. Great languages, libraries, and tools change the way you code. Moose qualifies as great. Moose includes a feature known as attribute builders. When you declare the attributes of an object, you can...]]></description>
			<content:encoded><![CDATA[
        <p>Great software changes the way you use computers. Great languages, libraries,
and tools change the way you code. <a href="http://moose.perl.org/">Moose</a>
qualifies as great.</p>

<p>Moose includes a feature known as attribute builders. When you declare the
attributes of an object, you can specify default values:</p>

<pre><code>use Moose;

has 'name', is =&gt; 'ro', default =&gt; 'Binky';</code></pre>

<p>When someone builds a new object of this type, they can provide a name for
the object, or get a default name of <code>Binky</code>.</p>

<p>For more dynamic behavior, provide a function reference as the default. For
example, if an object needs to know its creation time (and not the time the
system started):</p>

<pre><code>use Moose;
use DateTime;

has 'birthtime', is =&gt; 'ro', default =&gt; sub { DateTime-&gt;now };</code></pre>

<p>For even more flexibility, you can use the <em>name</em> of a method as the
builder. This allows you to customize the behavior further with a subclass,
role, or other mechanism:</p>

<pre><code>use Moose;
use DateTime;

has 'birthtime', is =&gt; 'ro', builder =&gt; '_build_birthtime';

sub _build_birthtime { DateTime-&gt;now };</code></pre>

<p>Overriding this builder is easy (far easier than intercepting all calls to
the object's constructor.) As another benefit, you know that because Moose
calls this builder during object construction, your object always gets
constructed in a consistent, known-good state. You can rely on it being
<em>correct</em> throughout the rest of its lifespan. (Obviously you have to
avoid poking into it to do the wrong things, but that's up to you.)</p>

<p>This feature in and of itself would be good, but Moose went further to make
it great. If you specify the attribute builder as <em>lazy</em>, Moose will
only call the builder when someone uses the attribute's accessor:</p>

<pre><code>use Moose;
use DateTime;

has 'first_access_time', is   =&gt; 'ro', builder =&gt; '_build_firstaccesstime',
                         lazy =&gt; 1;

sub _build_firstaccesstime { DateTime-&gt;now };</code></pre>

<p>This makes the most sense when calculating an attribute is somehow expensive
or the use of an attribute is rare. For example, I have an object which
represents the calculation and projection of ten year free cash flow growth of
a stock (like earnings, but measures liquid assets and less prone to
manipulation via accrual accounting methods). This object is responsible for
calculating the projected ten year average growth rate in free cash flow and
produces a graph of ten year trailing free cash flow, the trendline for those
ten years and ten years in the future, and projected growth curve ten years in
the future.</p>

<p>That requires some math.</p>

<p>That math has a lot of interdependencies. Finding a good trendline for
earnings which fluctuate means statistical analysis, such as with <a
href="http://search.cpan.org/perldoc?Statistics::Basic::LeastSquareFit">Statistics::Basic::LeastSquareFit</a>.
As it happens, the lazy <code>lsf</code> attribute nicely encapsulates that
statistics object. Further, the growth rate is another lazy attribute, as are
the sets of points of the trendline and the trend curve.</p>

<p>While the original proof of concept of this code performed all of the
calculations in one large function of a couple of hundred lines, the current
code is several methods of 10 - 50 lines apiece, with much better calculation
accuracy, and better factoring. This is all thanks to Moose's lazy
attributes.</p>

<p>The monolithic code was monolithic because I wanted to calculate everything
once and only once: growth rate, number of points on the lines and curves,
everything. Variables would stay in scope over tens and hundreds of lines
because I'd need to use them later.</p>

<p>By factoring individual calculations into their own lazy builders, I can
call the accessors when I need attribute data and everything snaps into place
behind the scenes thanks to Moose. Oh, and if I've already calculated the data
for the object, <em>it's already there</em>, and I don't have to recalculate
it.</p>

<p>Lazy attributes give me <a
href="http://search.cpan.org/perldoc?Memoize">memoization</a> for free, and I
don't even have to think about the data dependency graph of my calculations.
It's an emergent property of the source code. That's one more step in
expressing what I want to happen and not how to make it happen. Thanks,
Moose!</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/02/27/the-memoization-of-lazy-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>
	</channel>
</rss>

