<?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; perl5</title>
	<atom:link href="http://perlblogs.com/category/perl5/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>A Practical Use for Macros in Perl</title>
		<link>http://www.modernperlbooks.com/mt/2012/02/a-practical-use-for-macros-in-perl.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/02/a-practical-use-for-macros-in-perl.html#comments</comments>
		<pubDate>Fri, 03 Feb 2012 20:46:43 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[languagedesign]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=5cffcd700874d4b530e9c045dc4412b1</guid>
		<description><![CDATA[People occasionally ask for practical examples of macros when I lament the lack of macros in Perl 5. While I'm usually pleased at the degree to which Perl lets me design code to get and stay out of my way,...]]></description>
			<content:encoded><![CDATA[
        <p>People occasionally ask for practical examples of macros when I lament <a
href="http://www.modernperlbooks.com/mt/2011/11/what-the-perl-5-compiler-modules-could-have-been.html">the
lack of macros in Perl 5</a>. While I'm usually pleased at the degree to which
Perl lets me design code to get and stay out of my way, sometimes its
abstractions just aren't quite <em>enough</em> enough to remove all of the
duplication available.</p>

<p>(I've been refactoring one of our business projects in preparation for another round of deployment in the next couple of weeks. We could launch without these improvements, but administrative work took almost two weeks longer than the afternoon I'd planned for it, so I decided it was worth my time to <a href="http://www.modernperlbooks.com/mt/2011/11/on-technical-friction.html">reduce technical friction</a> so that further improvements are easier. More users means more work, so why not accelerate that work while I have the chance? I have another longer technical post to write to praise the use of Moose roles for a plugin system and to show off the stupidly-great task launcher, but that's for later.)</p>

<p>I found myself writing two code couplets that were similar enough they
triggered my "Hey, refactor away this duplication!" alert. It's extra
sensitive, because I <em>know</em> I'll have a few more couplets like this in
the very near future:</p>

<pre><code>while (my $stock = $stock_rs-&gt;next)
{
    my $pe_update = $self-&gt;analyze_pe( $stock );
    $stock_txn-&gt;add( $pe_update ) if $pe_update;

    my $cash_yield_update = $self-&gt;analyze_cash_yield( $stock );
    $analysis_txn-&gt;add( $cash_yield_update ) if $cash_yield_update;
}</code></pre>

<p>The <code>*_txn</code> variables contain objects representing deferred and
scoped SQL updates. I'll talk about that at <a
href="http://act.yapcna.org/2012/">YAPC::NA 2012</a> in <a
href="http://act.yapcna.org/2012/talk/50">When Wrong is Better</a>.</p>

<p>The general pattern is this: for every stock in the appropriate resultset,
call a method in this plugin. The method will return nothing if it fails (or
has nothing to do) or it will return data to be added to the appropriate
transaction. I have at least two types of transactions available here at the
moment, and may have more later: one transaction updates stock data and the
other updates analysis data.</p>

<p>I have several options. I could rework the data model so that this stage
always only updates one transaction, in which the loop body could instead look
like:</p>

<pre><code>{
    for my $method (qw( analyze_pe analyze_cash_yield ))
    {
        next unless my $result = $self->$method( $stock );
        $txn->add( $result );
    }
}</code></pre>

<p>This technique of hoisting the variants into an ad hoc data structure and
using existing looping techniques works well sometimes. (I use it in other
parts of the system.) It's relatively easy to expand, even though it moves
interesting information ("I'm calling the <code>analyze_pe</code> method!") to
a place where tools have more trouble finding it. (I search for
<code>&gt;analyze_pe</code> when I want to find method calls.) You may have used something similar to define several parametric methods at <code>BEGIN</code> time. It's the same type of pattern, and while Perl 5 provides most of the tools necessary to allow this, it doesn't natively express this pattern well.</p>

<p>I could also change the transaction object's <code>add()</code> method to do
nothing when it receives an empty list of arguments. I like that in some ways,
but I don't like it in others. I've come down on the side of keeping its
invariant (it always takes only one scalar as an object) pure for now. If I
change it to take a list of updates, that might be the right time to reconsider
this.</p>

<p>What I notice in the code as it stands right now is that the individual
variables <code>$pe_update</code> and <code>$cash_yield_update</code> are
synthetic variables. They only exist to support the code as written; they're
not necessary for the algorithm. If I were to modify this code but only this code, I'd really rather write:</p>

<pre><code>{
    ADD_TXN_WITH( $self, analyze_pe,         $stock, $stock_txn    );
    ADD_TXN_WITH( $self, analyze_cash_yield, $stock, $analysis_txn );
}</code></pre>

<p>... though that syntax doesn't thrill me either. The clearest possibility I
see right now is:</p>

<pre><code>{
    $stock_txn-&gt;add(    SKIP unless $self-&gt;analyze_pe( $stock )         );
    $analysis_txn-&gt;add( SKIP unless $self-&gt;analyze_cash_yield( $stock ) );
}</code></pre>

<p>... where <code>SKIP</code> does some magic to move to the next statement,
not the next loop iteration. (I have some ideas how to write XS to make this
work, but that creepy yak needs a shave and some mouthwash.)</p>

<p>The second best option right now is adding a function or method as
indirection to encapsulate the synthetic code. I'd rather avoid synthetic code,
but at least it reduces the possibility of copy and paste bugs.</p>

<p>For now, with only two steps in this analysis, I'm leaving it as it is. Two
repetitions of something this similar set off my refactoring alarm, but I
resist the urge for refactorings this small until I see three instances of
near-duplicate code.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/02/03/a-practical-use-for-macros-in-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speed up Perlbrew with Test Parallelism</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/speed-up-perlbrew-with-test-parallelism.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/speed-up-perlbrew-with-test-parallelism.html#comments</comments>
		<pubDate>Fri, 27 Jan 2012 21:20:46 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[perlbrew]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=cbc7696535dd728de1ef9d6b55e34b5a</guid>
		<description><![CDATA[Steven Haryanto's Perl First World Problems #1 reminded me of something I've taken for granted lately. You may have read my Controlling Test Parallelism with prove and Parallelism and Test Suites. I still have Test::Harness parallelism enabled by default on...]]></description>
			<content:encoded><![CDATA[
        <p>Steven Haryanto's <a href="http://blogs.perl.org/users/steven_haryanto/2012/01/perl-first-world-problems-1.html">Perl First World Problems #1</a> reminded me of something I've taken for granted lately.</p>

<p>You may have read my <a
href="http://www.modernperlbooks.com/mt/2011/12/controlling-test-parallelism-with-prove.html">Controlling
Test Parallelism with prove</a> and <a
href="http://www.modernperlbooks.com/mt/2011/11/parallelism-and-test-suites.html">Parallelism
and Test Suites</a>. I still have <code>Test::Harness</code> parallelism
enabled by default on most of the machines where I install my own Perls. While
I haven't yet filed tickets and tried to write patches for modules which need a
little help to run tests in parallel, I've only found a few lately that need
work. That's nice&mdash;having a module install through <code>cpanm</code> in
five seconds is a lot better than ten seconds or more. (I like
<code>cpanm</code> because it's <em>fast</em> and quiet, and part of its speed
comes from not printing to the console.)</p>

<p>I like instant feedback.</p>

<p>Like Steven, I noticed quite a while that installing a custom Perl through <a href="http://perlbrew.org/">perlbrew</a> takes a while, but then I remembered that a lot of work went into the Perl 5 test suite to make tests run in parallel. (We did something similar with Parrot several years ago, and it changed the way I work forever.)</p>

<p>To run core tests in parallel, set the environment variable
<code>TEST_JOBS=<em>n</em></code>, where <em>n</em> depends on your computer. I
use a value of 9 on a quad-core machine; in practice, that tends to keep the
CPU busy while not blocking anything too long on IO. You can set it globally in
your shell's configuration file or create an alias or wrapper for
<code>perlbrew</code>.</p>

<p>As most of the time spent compiling and installing Perl 5 through perlbrew
goes to running the test suite, this has saved me a measurable amount of
time.</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/27/speed-up-perlbrew-with-test-parallelism/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoiding The Vendor Perl Fad Diet</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/avoiding-the-vendor-perl-fad-diet.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/avoiding-the-vendor-perl-fad-diet.html#comments</comments>
		<pubDate>Wed, 25 Jan 2012 19:46:20 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[distributions]]></category>
		<category><![CDATA[p5p]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=c76c09804e86429f483ba7aab2bb1fe7</guid>
		<description><![CDATA[Here we go again. It looks like Red Hat is distributing Perl without the core library ExtUtils::MakeMaker. If you're not familiar with the details of the Perl 5 build chain, all you need to know is this: without MakeMaker, you're...]]></description>
			<content:encoded><![CDATA[
        <p>Here we go again.</p>

<p>It looks like <a
href="http://www.nntp.perl.org/group/perl.perl5.porters/2012/01/msg182360.html">Red
Hat is distributing Perl without the core library
<code>ExtUtils::MakeMaker</code></a>. If you're not familiar with the details
of the Perl 5 build chain, all you need to know is this: without MakeMaker,
you're not installing anything from the CPAN.</p>

<p>Ostensibly Red Hat and other OS distribution vendors split up Perl 5 into
separate packages to save room on installation media. Core Perl 5 is large and
includes many, many things that not everyone uses all the time... but <a
href="http://www.nntp.perl.org/group/perl.perl5.porters/2012/01/msg182376.html">the
obvious reaction to defining a core subset of Perl 5 that a vendor can call
"perl"</a> is another of those recurring discussions which never quite goes
anywhere.</p>

<p>For example, who needs the documentation just to run code? (Except that the
<code>diagnostics</code> pragma relies on the existence of
<em>perldiag.pod</em> to run.) Who needs the huge Unicode encoding tables for
ideographic languages such as you might find in Japan, China, Korea, and other
Asian locals? (Answer: Asia.) Who needs the ability to install code from the
CPAN? (Answer: users.)</p>

<p>While there's a lot of stuff in the core that probably doesn't need to be in
the core, or at least installed by default (a LaTex formatter for POD, the <a
href="http://search.cpan.org/perldoc?Switch">deprecated Switch module</a>, Perl
5.005 <a href="http://search.cpan.org/perldoc?Thread">Thread</a> emulation),
one thing is both clear and almost never said.</p>

<p>I'll give you a moment to think about it.</p>

<p>Here's a hint: you're usually better off compiling and installing your own
Perl 5 under your complete control such that you can compile in options you
want (64-bit integers, for example) and out options you don't (threading
imposes a 15% performance penalty even in the single-threaded case) and so that
you can manage your own library paths without changing the behavior of the
system). <a href="http://perlbrew.org/">perlbrew</a> changes the game. Learn
it, like it, love it.</p>

<p>The perpetual discussion misses one important point:</p>

<p>The vendor <code>perl</code>&mdash;especially on installation media&mdash;is
not for general purpose Perl programming. It's there only to support basic
administrative programs provided with the system as a whole. <em>That's</em>
why you don't replace the system Perl. <em>That's</em> why you don't mess with
the system CPAN modules. That's why you fence off whatever's in
<em>/usr/bin/perl</em> like it's Yucca Mountain and you're stuck with a '50s
reactor design instead of something safe and clean.</p>

<p>Vendors can tune and tweak that Perl to their satisfaction to provide just
what they need to install and configure a working system. They can keep it as
crufty and out of date as they like. When it breaks, they get to keep all of
the pieces and sew them back together like some sort of Fedorastein's monster.
They just can't let it out of the lab.</p>

<p>This of course means that they need to provide packages of Perl 5 Actual for
users and developers such that it's the full core of Perl 5. (It'd be nice if
they called not-a-perl as such, but one thing at a time.)</p>

<p>You can't predict what users will and won't do. That's why you code
defensively. The moment distributions started carving up Perl to install just
the little bits they needed in the hopes that their guesses as to what users
wanted were right, they put everyone in a bind.</p>

<p>Certainly Perl 5 could benefit from a thorough review of what's in core and
why, but I suspect that even if p5p came up with packaging guidelines for all
of the imaginable use cases and combinations of distributor needs and user
wants, it still wouldn't solve the real problem.</p>

<p>(Credit Allison Randal for pointing out the real problem <em>years</em> ago. We've discussed several times the idea of a stripped-down VM for a real language&mdash;something with better abstraction and reuse than Bash&mdash;with easy access to libraries and a very small footprint, but it's a bigger job than either of us could accomplish. It's still a righter approach than bowdlerizing an upstream distribution.)</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/25/avoiding-the-vendor-perl-fad-diet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Imagine if caller() Returned Stack-Capturing Objects</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/imagine-if-caller-returned-stack-capturing-objects.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/imagine-if-caller-returned-stack-capturing-objects.html#comments</comments>
		<pubDate>Wed, 18 Jan 2012 22:13:36 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[features]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=47fb4f1abad1303711ce188263f3f9a5</guid>
		<description><![CDATA[Imagine if Perl 5's caller returned an object which represented the call chain to the point of the object's creation. I want to inspect the call stack within a helper module, but I don't care about the call stack within...]]></description>
			<content:encoded><![CDATA[
        <p>Imagine if Perl 5's <a
href="http://perldoc.perl.org/perlfunc.html#caller"><code>caller</code></a>
returned an object which represented the call chain to the point of the
object's creation.</p>

<p>I want to inspect the call stack within a helper module, but I don't care about the call stack <em>within</em> the module. I want to use lots of little helper functions, because that's good design, but <code>caller</code> works against that. Looking up the stack means keeping track of the magic number of call frames within my module I currently use, and that's one more thing to update when I change things.</p>

<p>That's structural code highly coupled to the arrangement of other code, and
if that doesn't wrinkle your nose with the subtle aroma of fragility and peril,
I don't know what will.</p>

<p>Imagine if instead:</p>

<pre><code>my $caller_object = capture_caller_state();

while (my $call_frame = $caller_object-&gt;next)
{
    next if $call_frame-&gt;is_eval;
    say $call_frame-&gt;location_as_string;
    my $next_frame = $call_frame-&gt;previous;
    ...
}</code></pre>

<p>Imagine if you could <em>pass this object around</em>.</p>

<p>I know things get complicated if you pass this object up the call chain, but
stack unwinding is a solved problem in that anyone capable of recognizing the
problem should be able to figure out cheap and easy ways to fix it.</p>

<p>Alas, Perl 5.14 doesn't have this feature, and it's probably too late for
5.16 to get it, so for today I'm stuck imagining what might be.</p>

<p>(If you've never thought about this sort of thing before, you owe it to yourself to learn more about <a href="http://c2.com/cgi/wiki?ContinuationPassingStyle">Continuation Passing Style</a>, which is at least an order of magnitude more mind-bending at the start and at least two orders of magnitude more useful.)</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/19/imagine-if-caller-returned-stack-capturing-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing Your Templates, and Why It Doesn&#8217;t Always Work</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/testing-your-templates-and-why-it-doesnt-always-work.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/testing-your-templates-and-why-it-doesnt-always-work.html#comments</comments>
		<pubDate>Tue, 17 Jan 2012 19:29:28 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=987c9dfb8f15db4a986dca372f180e59</guid>
		<description><![CDATA[Sometimes you find bugs in the most surprising places. I've long used test-driven design for code I care about. Knowing that it works, works reliably, and will continue to work helps me write the right thing. As I've gained experience...]]></description>
			<content:encoded><![CDATA[
        <p>Sometimes you find bugs in the most surprising places.</p>

<p>I've long used <a
href="http://www.modernperlbooks.com/mt/2011/10/reimplementing-the-wheel-not-the-road.html">test-driven
design</a> for code I care about. Knowing that it works, works reliably, and
will continue to work helps me write the right thing. As I've gained experience
with testing, I've come to appreciate the nuances of how and what to test and
why. For example, I often don't bother to test exploratory code&mdash;it's more
important for me to learn how code might work to help me figure out how to
design the real thing than it is to hew to a rigid mindset of "You must always
test everything."</p>

<p>Similarly, I see little value in rigorously testing basic accessors, and thank goodness for <a href="http://moose.perl.org/">Moose</a> for turning class declarations into declarative code.<p>

<p>In more serious discussions of testability and testing, people often argue
that testing UIs is impossible, or merely difficult, or rarely worth the
trouble to do so completely. I agree to some respect; the most effective way
I've seen to test UIs is to test the backend data model rigorously, write a
very thin controller to marshall and unmarshall requests and responses, then to
write a handful of tests which explore the edge cases of UI interactions. That
requires a deep understanding of what happens for each interaction, and you can
only test those interactions which produce measurable side effects.</p>

<p>Let that latter point sink in for a moment.</p>

<p>My most recent work on multiple projects includes a lot of embarrassingly
parallel batch processing work, where the user interface is largely static,
produced daily from a series of templates. <em>Generally</em> the templates are
correct if they pass the eyeball test with live data.</p>

<p>This works except when it doesn't.</p>

<p>Consider a snippet of <a href="http://search.cpan.org/perldoc?Template">Template Toolkit</a> code to display a list of stories:</p>

<pre><code>[% FOR e IN entries %]
    &lt;div class="story story[% loop.count %]"&gt;
        &lt;h3&gt;&lt;a href="[% e.url %]"&gt;[% e.title %]&lt;/a&gt;&lt;/h3&gt;
        &lt;p&gt;[% IF e.author %]
            [% e.author | html %]&lt;br /&gt;
        [% END %]
        [% f.format( e.posted_time ) %]&lt;/p&gt;
        [% IF e.has_image %]
            &lt;img src="[% e.image.full_file %]" alt="[% e.title | html %] image" class="image" /&gt;
        [% END %]
        &lt;p&gt;[% e.short_content | html %] &lt;a href="[% e.url %]"&gt;Read More&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
[% END %]</code></pre>

<p>That code had a bug. Can you find it by eyeballing it? Neither could I, for
a long time. I'll give you a hint: it never displayed images associated with
stories. Give up?</p>

<p>I wrote backend test after backend test, fixing a couple of other bugs along
the way, then traced through the code in a debugging batch until I had
convinced myself that the data model was completely correct. The bug
<em>had</em> to be in the template because it could be nowhere else.</p>

<p>Rigorous template tests didn't seem to help either, and I'd almost convinced myself that I had a nasty spooky action at a distance bug somewhere in the data model before I saw the problem:</p>

<pre><code>[% IF e.has_image %]
    &lt;img src="[% e.image.full_file %]" alt="[% e.title | html %] image" class="image" /&gt;
[% END %]</code></pre>

<p>When I added a test for the <code>has_image()</code> method on story objects
to the data model tests, it failed immediately <em>because that method did not
exist</em>. It used to exist, but a refactoring somewhere went too far and
removed that method and its tests from everything except the template. Because
Template Toolkit is not so strict about the distinction between method and
property access, the lack of a method is no big deal. It fell back to property
access on a hash and, finding no such value in the hash, returned a false
value.</p>

<p>There are ways to fix this. I'm sure there's a plugin for Template Toolkit,
and probably a debugging/diagnostic mechanism somewhere I haven't yet
discovered. Yet the problem remains.</p>

<p>I've heard it said (Rich Hickey? Martin Odersky? I think it was Rich.) that
every bug in your program has passed the type checker. That statement contains
wisdom. Yet it's also true that every bug in your program has passed the test
suite. (We assume you run with type checks and keep your test suite fully
passing.)</p>

<p>Neither is a substitute for careful thought and understanding. Both protect you only as far as you can take advantage of them.</p>

<p>My next post will explore some options for making these kinds of errors
easier to catch way before the point of weird debugging sessions.</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/17/testing-your-templates-and-why-it-doesnt-always-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modern Perl 2011-2012 Edition Released!</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/modernperl-2011-2012-edition-released.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/modernperl-2011-2012-edition-released.html#comments</comments>
		<pubDate>Thu, 12 Jan 2012 20:38:31 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=f317a73ec6312d9f4a2ff14e7f23644d</guid>
		<description><![CDATA[The Modern Perl book went to the printer earlier this week; this is the 2011-2012 edition. You can already preorder Modern Perl: 2011-2012 from Amazon and it'll be available from other bookstores in the next couple of days. I expect...]]></description>
			<content:encoded><![CDATA[
        <p>The <a href="http://onyxneon.com/books/modern_perl/index.html">Modern Perl book</a> went to the printer earlier this week; this is the 2011-2012 edition.</p>

<p>You can already <a href="http://www.amazon.com/Modern-Perl-chromatic/dp/0977920178/?tag=onyxneopre-20">preorder Modern Perl: 2011-2012 from Amazon</a> and it'll be available from other bookstores in the next couple of days. I expect copies to ship by early next week.</p>

<p>What's new?</p>

<p>I closed every bug filed against the previous edition&mdash;a handful of typos, a few confusing sections, and some suggestions on improvements. I took most of these suggestions.</p>

<p>I also revised almost every paragraph of the book, even at the sentence level. While I'm proud of the first edition, this new edition is clearer, shorter, more concise, and more accurate.</p>

<p>I removed some sections that didn't work. This didn't amount to much, but
some of the things I recommended made little sense anymore and some of the
experimental modules I mentioned turned out to be less useful than hoped. You
won't miss them. This includes a big revision of the smart matching section in
anticipation of changes in 5.16 and 5.18 (simplicity is the rule of the day;
the simpler your use of the operator, the less risk you face for confusing
behavior and edge cases).</p>

<p>I also added explanations for the new features in Perl 5.14, especially the
<code>/r</code> modifier on regular expressions, and prepared for further
features added in 5.16.</p>

<p>You might notice subtle improvements in formatting; the font size used for
code examples is larger and callouts are much more attractive. We're still
experimenting with the best way to format books to make readable text while
avoiding brick-sized tomes, so feedback is more than welcome.</p>

<p>As with the first edition, we'll make electronic versions available for free
from the Onyx Neon site. We hope to have ePub versions ready in the next two
weeks. We'll also put raw HTML online on modernperlbooks.com at the same time
(this also allows us to link to translations with greater ease). In addition,
we're making most of our publishing tools available as CPAN distributions,
including the formatting modules (<code>Pod::PseudoPod::DOM</code>) and the
rendering pipeline (<code>Pod::PseudoPod::Book</code>). This will allow you to
make your own version of the book in other languages if you desire, or to
create new and attractive books in many formats. We'll make our own Kindle
version, rather than using Amazon's conversion tools (they didn't work as well
as we'd hoped), and we hope to get the book in the Nook store as well.</p>

<p>We plan to release a new version of the book late this year or early next
year to cover 5.14 and 5.16. We'll almost certainly drop support and mention of
5.10.</p>

<p>We couldn't have done this book without you. Thanks for reading. Please
share with your friends.</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/12/modern-perl-2011-2012-edition-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modern::Perl Updates</title>
		<link>http://www.modernperlbooks.com/mt/2012/01/modernperl-updates.html</link>
		<comments>http://www.modernperlbooks.com/mt/2012/01/modernperl-updates.html#comments</comments>
		<pubDate>Thu, 05 Jan 2012 20:34:04 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=e111c8530c409abb316f409fa5f73041</guid>
		<description><![CDATA[The Modern::Perl CPAN distribution is much more conservative than I think most people thought it would be when I first released it. (Count me in that group.) Where I once intended to collect a bunch of useful CPAN modules in...]]></description>
			<content:encoded><![CDATA[
        <p>The <a href="http://search.cpan.org/perldoc?Modern::Perl">Modern::Perl</a> CPAN distribution is much more conservative than I think most people thought it would be when I first released it. (Count me in that group.) Where I once intended to collect a bunch of useful CPAN modules in the style of <a href="http://search.cpan.org/perldoc?Task::Kensho">Task::Kensho</a> or <a href="http://search.cpan.org/perldoc?perl5i">perl5i</a>, both of those do what they do far better than I can do.</p>

<p>Instead, I see Modern::Perl as enabling the core features I wish were on out
of the box by default in Perl 5. While it'd be nice to pull in <a
href="http://search.cpan.org/perldoc?Try::Tiny">Try::Tiny</a> and sometimes I
might wish for fatal warnings, the former is not a core module and the second
isn't something I use in every program.</p>

<p>Consequently the module hasn't needed much maintenance. Yet I've added a couple of missing features that should keep it useful and usable into the
future. I uploaded a new version yesterday and will upload one more today with a little bit more polish.</p>

<p>First, it now requires <a
href="http://search.cpan.org/perldoc?autodie">autodie</a> as a distribution
dependency. It doesn't <em>load</em> <code>autodie</code>, but installing
Modern::Perl on 5.10.0 will also install <code>autodie</code>. (Anything 5.10.1
and newer includes <code>autodie</code> in the core.) You don't have to use it,
but now you can rely on any Perl considered modern to have <code>autodie</code>
available.</p>

<p>Second, it now loads <a
href="http://search.cpan.org/perldoc?IO::File">IO::File</a> and <a
href="http://search.cpan.org/perldoc?IO::Handle">IO::Handle</a> so that you can
call methods on lexical filehandles without having to load either manually.
Perl 5.14 fixed that usability niggle, but Modern::Perl fixes this for people
using 5.10 or 5.12. (Why both? I can never remember which one superseded the
other in 5.12, but better safe than sorry. I welcome a patch to load one over
the other with a version check&mdash;and please test carefully.)</p>

<p>Third, I added unimporting support so that you can write <code>no
Modern::Perl;</code> within a scope to disable strictures, warnings, and
language bundle features. It's an all or nothing switch and will remain that
way, but I can see this being useful in specific cases, especially when
updating older code in stages.</p>

<p>Finally I added date support to importing. If you write <code>use
Modern::Perl;</code> you'll get the features of Perl 5.10 (with the caveat that
if you're using Perl 5.11.3 or newer, you also get the
<code>unicode_strings</code> feature, of which all you're likely to notice is
that Unicode strings work better in more places).</p>

<p>Yet for forward compatibility, you should be using:</p>

<pre><code>use Modern::Perl 2012;</code></pre>

<p>... which enables 5.14 features. You can use 2009 and 2010 to get 5.10
features and 2011 to get 5.12 features. If you use the wrong date on the wrong
version of Perl 5, you'll get an error, which is as it should be.</p>

<p>Next year I'm likely to drop support for Perl 5.10, in which case you'll
probably get an error message that that year isn't modern enough, but I could
be convinced to do a version check instead. I haven't decided. The tradeoff is
between providing a minimal module suitable for use in programs which helps
people write better code from the start and between telling people what they
should and shouldn't use. Besides all that, the relevant code is only a couple of dozen lines of very simple Perl. Anyone reading this can reimplement it almost trivially.</p>

<p>Of course, this all comes about because the <a
href="http://onyxneon.com/books/modern_perl/index.html">Modern Perl book</a>
goes to the printer today. We're very proud of the new 2011-2012 edition which
concentrates on Perl 5.12 and Perl 5.14. It addresses all of the known typos
and confusing parts of the previous edition, covers new features in Perl 5.14,
and is, from all reports, even better than the first edition.</p>

<p>The book should be in stores in the next week or so, and we'll have
electronic editions up this month for free download and redistribution. (We
hope you tell lots of people to buy the print edition because it's great and
more people need it on their desks, but sharing is caring and we support
that.)</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2012/01/05/modernperl-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Would You Track User Behavior with Plack and Catalyst?</title>
		<link>http://www.modernperlbooks.com/mt/2011/12/how-would-you-track-user-behavior-with-plack-and-catalyst.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/12/how-would-you-track-user-behavior-with-plack-and-catalyst.html#comments</comments>
		<pubDate>Mon, 19 Dec 2011 21:41:44 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[plack]]></category>
		<category><![CDATA[webprogramming]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=e64ae5b969a76f8b0fd4763a0b554159</guid>
		<description><![CDATA[One of the persistent questions which keeps entrepreneurs on the edge is &#34;Are we building the right thing?&#34; In the first web bubble, the Silly side of Silicon Valley chased vanity metrics such as &#34;the number of eyeballs on the...]]></description>
			<content:encoded><![CDATA[
        <p>One of the persistent questions which keeps entrepreneurs on the edge is
"Are we building the right thing?"</p>

<p>In the first web bubble, the Silly side of Silicon Valley chased vanity
metrics such as "the number of eyeballs on the site" and "brand awareness" and
"unique visitors". Those numbers are only interesting when you can correlate
them to producing value for customers and bringing in real cash in the form of
revenue.</p>

<p>I've enjoyed the book <a
href="http://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898?tag=onyneopre-20">The
Lean Startup</a> by Eric Ries because he offers a much better mechanism to
track the success or failure of any attempt to produce real value to customers.
While split testing (or A/B testing) is useful to see how small changes lead to
different customer behaviors, Ries recommends <a
href="http://www.avc.com/a_vc/2009/10/the-cohort-analysis.html">cohort
analysis</a>, where you can see the behavior of real customers through the <a
href="http://www.mindtools.com/pages/article/newLDR_94.htm">sales funnel</a>
and correlate the X-axis with individual changes to your business or
product.</p>

<p>That means tracking customer behavior. If you're building some sort of
software as a service product, and if the mechanism of delivery of that product
is primarily a web site, you probably already know the punchline.</p>

<p>Assume I already know how to identify and log events for each salient
customer action type. (I've built that kind of system before.) Assume I don't
want to collect personally identifiable information (I don't). Assume I'm using
<a href="http://plackperl.org/">Plack</a> and its middleware heavily, and
assume I'm happy using <a href="http://catalystframework.org/">Catalyst</a> as
a web framework.</p>

<p>How can I identify unique users (with and without accounts) on a daily
basis, anonymize them, but group their actions across the site such that my
automated daily cohort graphs correspond with reality?</p>

<p>So far I've identified few points of possible contention. I can rely on
browser cookies for unique identification of users if I <em>know</em> that user
sessions have unique identifiers within a 24 hour period. (I could generate
GUIDs for this, but that may be overdoing things.) I <em>think<</em> I also
have to track the transition from anonymous visitor to authenticated user, but
I might be able to convince myself that either replacing the current session or
smple subtraction of successful login events from total number of unique
anonymous visitors would give the right numbers.</p>

<p>(I also haven't dived much into how Catalyst 5.9 and Plack interact in terms
of session and cookie handling. Everything's just worked, so I've ignored the
details until now.)</p>

<p>I don't mind building such a system if necessary, but if all of the pieces
are out there and available&mdash;or if someone's already built this and can
give guidance&mdash;so much the better.</p>

<p>Have you solved this problem? If so, how did you do it? If not, how would
you do it? Would you handle logging at the Plack level or the application
level? Would you worry about tracking session changes? Does Catalyst need to
know about this?</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/12/19/how-would-you-track-user-behavior-with-plack-and-catalyst/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>If We Could Resolve Predicates at Compile Time</title>
		<link>http://www.modernperlbooks.com/mt/2011/12/if-we-could-resolve-predicates-at-compile-time.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/12/if-we-could-resolve-predicates-at-compile-time.html#comments</comments>
		<pubDate>Mon, 12 Dec 2011 18:27:07 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[catalyst]]></category>
		<category><![CDATA[languagedesign]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[typing]]></category>
		<category><![CDATA[webprogramming]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=4e36ac66b0108e9ced4978e017bbe995</guid>
		<description><![CDATA[The Catalyst web framework uses Perl 5 function attributes effectively&#38;mdash;I've seen few more effective uses of attributes. Any modern web framework has to deal with the idea of routes and request routing somehow. Given a request path (such as /stocks/AA/view_analysis),...]]></description>
			<content:encoded><![CDATA[
        <p>The <a href="http://catalystframework.org/">Catalyst web framework</a> uses
Perl 5 <a
href="http://perldoc.perl.org/perlsub.html#Subroutine-Attributes">function
attributes</a> effectively&mdash;I've seen few more effective uses of
attributes.</p>

<p>Any modern web framework has to deal with the idea of routes and request
routing somehow. Given a request path (such as <em>/stocks/AA/view_analysis</em>),
how does your application know what to do?</p>

<p>Catalyst solves this elegantly with a feature known as chained actions.
Controller methods can consume zero or more parts of the path but, when
explicitly chained, can combine. Consider the example request path. The
controller is <em>Stocks.pm</em>. The second component of the path
(<em>/AA</em>) is the identifier for a stock (<a
href="http://www.alcoa.com/global/en/home.asp">Alcoa</a>, to be specific. I'm
neither long nor short on Alcoa itself, though I probably own some shares as
part of a fund somewhere.) The final component of the path,
<em>/view_analysis</em>, is an action&mdash;a verb representing an action the
controller should take on the object representing Alcoa in the system.</p>

<p>You can probably start to see the idea of the chain right away.</p>

<p>The Stock controller has a controller method called <c>get_stock</c> which
grabs the stock symbol from the request path, looks it up in the database, and
stores the object representing that stock for further processing. If no such
symbol exists, it throws an exception.</p>

<p>The <code>view_analysis</code> method chains off of the <c>get_stock</c>
method such that Catalyst will only dispatch to <code>view_analysis</code> when
it's already successfully dispatched to <c>get_stock</c>. Unless you write a
custom dispatch system which bypasses the dispatch rules, users will never be
able to call <code>view_analysis</code> without a valid stock object
available.</p>

<p>(Further, these methods are part of a chain which requires that users have
successfully logged into the system; they chain off of a user authentication
system.)</p>

<p>In code terms, the relevant attributes look something like:</p>

<pre><code>sub authorized :Chained('/login/required') :PathPart('stocks') :CaptureArgs(0);

sub get_stock :Chained('authorized') :PathPart('') :CaptureArgs(1);

sub view_analysis :Chained('get_stock') :PathPart('view_analysis') :Args(0);</code></pre>

<p>The <code>:Chained</code> attribute is most relevant here.
<code>:PathPart</code> governs how Catalyst's dispatcher makes each method
visible to user requests (<code>get_stock</code> doesn't consume a part of the
path on its own, while <code>authorized</code> consumes the name of the
controller and <code>view_analysis</code> consumes its own name).
<code>:CaptureArgs</code> and <code>:Args</code> control how many other pieces
of the path the methods consume; in the case of <code>get_stock</code>, it's
the single path element between <code>/stocks</code> and any subsequent chained
actions&mdash;in this case, <code>/AA</code>. As <code>view_analysis</code> is
the end point of a chain, you use <code>:Args</code> instead of
<code>:CaptureArgs</code>.</p>

<p>With that all explained, request method chaining is fantastic. I can reuse
<code>get_stock()</code> for other request methods and get all of its benefits,
including the fact that only authorized users can even reach this point.</p>

<p>Yet I want to <em>prove</em> these characteristics of my application.</p>

<p>I want to prove these features so definitively that I don't want to write
tests for them. I want my program to fail to <em>compile</em> if these
characteristics are untrue.</p>

<p>I see chaining from <code>get_stock()</code> as supplying an invariant
precondition to <code>view_analysis()</code> such that it proves, to my
satisfaction, that I can always rely on a valid stock object being available
within the analysis method. Always. Similarly, I can always rely on a valid
user being available within both methods. Always always.</p>

<p>The problem comes in that it's easy to make a typo in the name of a chain or
a method, or to use <code>:CaptureArgs</code> instead of <code>:Args</code> or
vice versa.</p>

<p>Here's the thing: all of this metadata is metadata. All of this information
is available at compile time, before Perl has to execute anything.</p>

<p>If I had a really good and extensible type system in Perl 5, I could write a
couple of pieces of predicate logic to say that every chained method should be
a starting point or have a valid predecessor. These are trivial properties of
my program (no matter how large it gets) and they're resolvable with the
information available at the point of compilation. Even with complex controller
construction through the use of roles and parametric roles, this information is
available.</p>

<p>I know how to emulate this behavior by injecting some sort of
<code>CHECK</code> block into the code and schlepping through the symbol table
and inspecting attributes myself, but that's emulating a useful feature we
could exploit in a lot of ways.</p>

<p>Forget the talk about making Perl into Java or C++ by adding a silly
manifest static type system. We could find and fix real errors in
logic&mdash;trivial errors, trivially discoverable&mdash;if we had an
extensible type system which let us define our own simple predicates.</p>

<p>(Implementing such is left as an exercise for a small army of readers cloned
from a very small army of brilliant p5p hackers with copious spare time and a
habit of reading ACM papers before breakfast.)</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/12/12/if-we-could-resolve-predicates-at-compile-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Track App Progress with Writeable $0</title>
		<link>http://www.modernperlbooks.com/mt/2011/12/track-app-progress-with-writeable-0.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/12/track-app-progress-with-writeable-0.html#comments</comments>
		<pubDate>Fri, 09 Dec 2011 19:46:26 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[modernperl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://perlblogs.com/?guid=53ef701997526a59561e88464811e94b</guid>
		<description><![CDATA[In Perl 5, $0 is the magic superglobal which contains the name of the program being executed. This is the name you see in the output of ps or in the top utility. Some clever programs provide several symlinks to...]]></description>
			<content:encoded><![CDATA[
        <p>In Perl 5, <code>$0</code> is the magic superglobal which contains the name
of the program being executed. This is the name you see in the output of
<code>ps</code> or in the <code>top</code> utility.</p>

<p>Some clever programs provide several symlinks to the main program and
examine <code>$0</code> to enable or disable certain behaviors. This is an easy
way to hide the details of execution from users while making those behavior
mnemonic.</p>

<p>I usually don't write those kinds of programs, but this past year I've
written several batch processing programs which have several interdependent
states. For example, one program runs from <code>cron</code> regularly to run
through a pipeline of behaviors. Data moves through that pipeline; it's
basically one big state machine.</p>

<p>The core of the program is a pipeline manager which runs the appropriate
processing stages in order, such that on every invocation, the program moves
data through at least one stage and potentially every stage. It doesn't have to
move everything through the pipeline all in one invocation, but it does have to
make progress on every invocation.</p>

<p>For various uninteresting optimization and locking reasons, I made this
program a single execution unit. (I do use asynchronous IO for things like
network access, but that's because the program is largely IO bound.) The
program also has copious logging of the stage traversal, split between one log
which tracks stage transitions and timings and stage-specific log files which
have more details on the progress of those stages.</p>

<p>Until a few minutes ago, the easiest way to see the program's current stage
was to <code>tail</code> the top-level log file. While running some live tests
on a new feature, I found myself with free time and the desire <em>not</em> to
switch back and forth to a <code>tail -f</code> screen again, so I checked the
documentation for <code>$0</code> again.</p>

<p>I knew that on certain platforms (GNU/Linux, which makes my life easier) you
can actually <em>write</em> to it. If you do this, you can control what appears
in the output of <code>ps</code> and <code>top</code>.</p>

<p>Every stage runs from a closure (shades of <a href="http://plackperl.org/">Plack</a>):</p>

<pre><code>
    my $sub    = sub
    {
        my ($self, $config) = @_;
        my $log             = $self-&gt;get_fh_for_step( $config, lc $app );

        # show app stage in ps output
        <strong>local $0 = $app;</strong>
        my $app  = $module-&gt;new(
            logger   =&gt; $log,
            map { $_ =&gt; $config-&gt;{General}{$_} } @keys,
        );

        $app-&gt;run;
        $log-&gt;log( sprintf $message, $app-&gt;count ) if $app-&gt;count;
    };</code></pre>

<p>A loop in the pipeline manager creates a new closure over the name of the
module which implements the stage to create a new object for the stage, set up
the logger, provide the appropriate configuration, and run the stage. The
emboldened code shows the change I made.</p>

<p>Right now, my <code>top</code> window shows that the image processing stage
has just given way to the report writing stage&mdash;and now the program has
exited. In a couple of minutes, everything will start again.</p>

<p>Writing this entry took longer than implementing this feature. Five minutes
of experimenting has improved the visibility and monitoring of this program
immensely. Maybe it'll help you.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/12/09/track-app-progress-with-writeable-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

