<?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>Open Swartz &#187; Perl</title>
	<atom:link href="http://www.openswartz.com/category/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.openswartz.com</link>
	<description>Perl and open source development</description>
	<lastBuildDate>Tue, 31 Jan 2012 06:51:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Stop running tests on install!</title>
		<link>http://www.openswartz.com/2012/01/31/stop-running-tests-on-install/</link>
		<comments>http://www.openswartz.com/2012/01/31/stop-running-tests-on-install/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 06:51:13 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=190</guid>
		<description><![CDATA[chromatic shows users how to run tests faster on cpanm and perlbrew installs. This strikes me as well-meaning advice that misses a much more basic point:
cpanm and perlbrew should not run tests by default.
This may sound heretical. Perl has always had a strong testing culture, and end-user testing may have once played a valuable role [...]]]></description>
			<content:encoded><![CDATA[<p>chromatic shows users how to <a href="http://www.modernperlbooks.com/mt/2012/01/speed-up-perlbrew-with-test-parallelism.html">run tests faster</a> on cpanm and perlbrew installs. This strikes me as well-meaning advice that misses a much more basic point:</p>
<p><em>cpanm and perlbrew should not run tests by default.</em></p>
<p>This may sound heretical. Perl has always had a strong testing culture, and end-user testing may have once played a valuable role in testing a distribution under many systems. But we now have a <a href="http://wiki.cpantesters.org/">CPAN Testers network</a> which will run tests on countless systems and Perl versions, and report failures back to the author promptly and automatically. Distributions can be sent through the Testers&#8217; gauntlet <a href="http://blogs.perl.org/users/buddy_burden/2012/01/a-tale-of-cpan-testers.html">before ever being officially released</a>. In this environment, it&#8217;s hard to see much additional value in ad hoc end-user testing.</p>
<p>As Dave Rolsky points out, we <a href="http://blog.urth.org/2009/05/the-real-problem-with-dependencies.html">install most other software without running tests</a> and rarely give it a thought.</p>
<p>None of this would matter if end-user testing was free. But it is not.</p>
<h3>The costs of end-user testing</h3>
<p><strong>Slower installs.</strong> On my system, a fresh install of <a href="http://search.cpan.org/perldoc?Moose">Moose</a> and its dependencies takes <em>three times</em> longer with tests (2 minutes versus 41 seconds). A fresh install of <a href="http://search.cpan.org/perldoc?Catalyst">Catalyst</a> and its dependencies takes nearly <em>four times</em> longer with tests (9.5 minutes versus 2.5 minutes).</p>
<p>How many new Perl users find CPAN installs much slower than they need to be? How many would choose a 3-4 times speedup if they knew it was an option? It&#8217;s like having a turbo button and leaving it unpressed by default.</p>
<p><strong>False positives.</strong> The more tests CPAN authors write, the more likely an occasional false-positive failure sneaks through (as in &#8220;Failed 1/1746 tests.&#8221;) In most such cases the module will still work for the user&#8217;s purposes. But the default behavior is to <em>prevent the module from being installed at all</em>. If your module depends on other modules, then any failure up the dependency chain likewise prevents your module from being installed, even if the failure has no bearing on your module&#8217;s efficacy.</p>
<p>How many new Perl users have unnecessarily failed to install a module like Moose or Catalyst because of an obscure, temporary failure deep in the dependency chain?</p>
<p><strong>Fear of dependencies and code reuse.</strong> Slower installs and false positives are the main reasons why people <a href="http://perlmonks.org/?node_id=760581">complain</a> about distributions having &#8220;too many dependencies&#8221;. (If the dependencies installed quickly and reliably, as they do with &#8211;notest and apt-get and yum, would anyone complain or even notice?) These  complaints in turn encourage module authors to <a href="http://perldancer.org/">reduce</a> or <a href="http://search.cpan.org/~ams/Mojolicious-2.46/lib/Mojolicious/Guides/FAQ.pod#Why_doesn%27t_Mojolicious_have_any_dependencies?">eliminate</a> their dependencies, thus reinventing where they could be reusing.</p>
<h3>It&#8217;s the wrong default for new users</h3>
<p>Some veteran Perl folks may like tests to run on every install. That&#8217;s fine. But I suspect <em>new</em> Perl users just want things to install quickly and reliably, and in any event don&#8217;t have the experience to evaluate or take action on a test failure (especially one in an obscure dependency). For these users running tests is simply the wrong default.</p>
<p>I turn on &#8211;notest on each system I administer and preach it enthusiastically to every new Perl user I encounter. But I wish I didn&#8217;t have to mention it at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2012/01/31/stop-running-tests-on-install/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>The inevitable Tie::CHI</title>
		<link>http://www.openswartz.com/2011/10/07/the-inevitable-tiechi/</link>
		<comments>http://www.openswartz.com/2011/10/07/the-inevitable-tiechi/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 12:51:20 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=183</guid>
		<description><![CDATA[Despite its lofty martial-arts name, Tie::CHI is a simple module that allows you to tie a hash to a persistent CHI cache, using any of CHI&#8217;s backends.
I hardly ever choose Tie interfaces &#8212; too much magic &#8212; but occasionally they do produce pretty code.  In this case, we have a watchdog script that sends [...]]]></description>
			<content:encoded><![CDATA[<p>Despite its lofty martial-arts name, <a href="http://search.cpan.org/perldoc?Tie::CHI">Tie::CHI</a> is a simple module that allows you to tie a hash to a persistent <a href="http://search.cpan.org/perldoc?CHI">CHI</a> cache, using any of CHI&#8217;s backends.</p>
<p>I hardly ever choose <a href="http://search.cpan.org/perldoc?perltie">Tie</a> interfaces &#8212; too much magic &#8212; but occasionally they do produce pretty code.  In this case, we have a watchdog script that sends USR2 signals to httpd processes that grow too large (so that they&#8217;ll log their call stack). Sometimes these processes stick around for a while, so I only want to send a certain number of signals per process.</p>
<pre><code>    my %kill_count;
    ...
    if ( $vsize &gt; $max_vsize ) {
        if ( $kill_count{$pid} &lt; $max_kills ) {
            kill( 'USR2', $pid );
            $kill_count{$pid}++;
            $log-&gt;warn(sprintf( "pid %d vsize %dmb &gt; %dmb, sending USR2",
                $pid, $vsize, $max_vsize ));
        }
    }
</code></pre>
<p>Then it occurred to me that the watchdog restarts frequently, so I need to keep the kill counts persistent; and I should only limit on an hourly basis, because the same pid will eventually come around again. We already have a custom CHI subclass that we use for caching all over our application, so it was easy to plug it in:</p>
<pre><code>    use Tie::CHI;
    my $cache = HM::Cache-&gt;new
       (namespace =&gt; 'watchdog/kill_count', expires_in =&gt; '1 hour');
    my %kill_count;
    tie %kill_count, 'Tie::CHI', $cache;
</code></pre>
<p>And voila, <code>%kill_count</code> is persistent, and its values decay after an hour.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2011/10/07/the-inevitable-tiechi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A faster memory cache for CHI</title>
		<link>http://www.openswartz.com/2011/03/02/a-faster-memory-cache-for-chi/</link>
		<comments>http://www.openswartz.com/2011/03/02/a-faster-memory-cache-for-chi/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 23:35:03 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=178</guid>
		<description><![CDATA[I&#8217;ve released CHI 0.41 with a RawMemory driver. It&#8217;s like the regular Memory driver except that data structure references are stored directly instead of serializing / deserializing. This makes the cache faster at getting and setting complex data structures, but unlike most drivers, modifications to the original data structure will affect the data structure stored [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released <a href="http://search.cpan.org/perldoc?CHI">CHI 0.41</a> with a <a href="http://search.cpan.org/perldoc?CHI::Driver::RawMemory">RawMemory</a> driver. It&#8217;s like the regular <a href="http://search.cpan.org/perldoc?CHI::Driver::Memory">Memory</a> driver except that data structure references are stored directly instead of serializing / deserializing. This makes the cache faster at getting and setting complex data structures, but unlike most drivers, modifications to the original data structure <em>will</em> affect the data structure stored in the cache, and vica versa. e.g.</p>
<pre><code>   my $cache = CHI-&gt;new( driver =&gt; 'Memory', global =&gt; 1 );
   my $lst = ['foo'];
   $cache-&gt;set('key' =&gt; $lst);   # serializes $lst before storing
   $cache-&gt;get('key');   # returns ['foo']
   $lst-&gt;[0] = 'bar';
   $cache-&gt;get('key');   # returns ['foo']

   my $cache = CHI-&gt;new( driver =&gt; 'RawMemory', global =&gt; 1 );
   my $lst = ['foo'];
   $cache-&gt;set('key' =&gt; $lst);   # stores $lst directly
   $cache-&gt;get('key');   # returns ['foo']
   $lst-&gt;[0] = 'bar';
   $cache-&gt;get('key');   # returns ['bar']!
</code></pre>
<p>It should work well as a short-lived <a href="http://search.cpan.org/perldoc?CHI#L1_cache">L1 cache</a> in front of memcached, for example.</p>
<p>I was motivated to create this by Yuval Kogman&#8217;s <a href="http://search.cpan.org/perldoc?Cache::Ref">Cache::Ref</a>, which is still a little faster (not having some of the overhead of CHI&#8217;s metadata and features). See the <a href="http://search.cpan.org/perldoc?CHI::Benchmarks">CHI benchmarks</a>, also new with this release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2011/03/02/a-faster-memory-cache-for-chi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mason has routes</title>
		<link>http://www.openswartz.com/2011/02/25/mason-has-routes/</link>
		<comments>http://www.openswartz.com/2011/02/25/mason-has-routes/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 04:44:05 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=172</guid>
		<description><![CDATA[For those using Mason 2&#8217;s request dispatching features, I just released Mason::Plugin::RouterSimple, which adds basic route support courtesy of Router::Simple.
Let&#8217;s say we want to support URLs like
    /archives/2010/05

where the second and third part of the path are year and month parameters respectively.
Using the new plugin:
    %% route "{year:[0-9]{4}}/{month:[0-9]{2}}";

  [...]]]></description>
			<content:encoded><![CDATA[<p>For those using Mason 2&#8217;s <a href="http://search.cpan.org/perldoc?Mason::Manual::RequestDispatch">request dispatching</a> features, I just released <a href="http://search.cpan.org/perldoc?Mason::Plugin::RouterSimple">Mason::Plugin::RouterSimple</a>, which adds basic route support courtesy of <a href="http://search.cpan.org/perldoc?Router::Simple">Router::Simple</a>.</p>
<p>Let&#8217;s say we want to support URLs like</p>
<pre><code>    /archives/2010/05
</code></pre>
<p>where the second and third part of the path are year and month parameters respectively.</p>
<p>Using the new plugin:</p>
<pre><code>    %% route "{year:[0-9]{4}}/{month:[0-9]{2}}";

    Archives for the month of &lt;% $.month %&gt;/&lt;% $.year %&gt;:
    ...

    &lt;%init&gt;
    # Use $.month and $.year to fetch the archives
    &lt;/%init&gt;
</code></pre>
<p>The <code>route</code> command adds a route indicating how the <em>path_info</em> (the remainder of the path beyond <code>/archives</code>) should be parsed.</p>
<p>Any named captured arguments are placed in component attributes, which are declared automatically if you don&#8217;t do so manually. So above, we get auto-declared attributes <code>$.year</code> and <code>$.month</code> that are then set to &#8216;2010&#8242; and &#8216;05&#8242; for that URL.</p>
<p>You can add multiple routes and they&#8217;ll each be tried in turn. If the URL does not match any route, the component will decline, which generally results in a 404.</p>
<p>Other examples of <code>Router::Simple</code> routes:</p>
<pre><code>    route "wiki/:page";     # sets $.page
    route "download/*.*";   # sets $.splat to a 2-element arrayref
</code></pre>
<p>I chose <code>Router::Simple</code> because I liked the compact declaration syntax, but one could create similar plugins (with some shared common code) to support other routers like <a href="http://search.cpan.org/perldoc?Path::Dispatcher">Path::Dispatcher</a> and <a href="http://search.cpan.org/perldoc?Path::Router">Path::Router</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2011/02/25/mason-has-routes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing Mason 2</title>
		<link>http://www.openswartz.com/2011/02/21/announcing-mason-2/</link>
		<comments>http://www.openswartz.com/2011/02/21/announcing-mason-2/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 17:19:56 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=165</guid>
		<description><![CDATA[I&#8217;m pleased to announce Mason 2, the first major version of Mason in ten years.
For those not familiar with it, Mason is a templating framework for generating web pages and other dynamic content. Mason 2 has been rearchitected and reimplemented from the ground up, to take advantage of modern Perl techniques (Moose, Plack/PSGI) and to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce <a href="http://search.cpan.org/perldoc?Mason">Mason 2</a>, the first major version of Mason in ten years.</p>
<p>For those not familiar with it, Mason is a templating framework for generating web pages and other dynamic content. Mason 2 has been rearchitected and reimplemented from the ground up, to take advantage of modern Perl techniques (<a href="http://search.cpan.org/perldoc?Moose">Moose</a>, <a href="http://plackperl.org">Plack/PSGI</a>) and to correct long-standing feature and syntax inadequacies. Its new foundations should allow its performance and flexibility to far exceed Mason 1.</p>
<p>Though little original code or documentation remains, Mason&#8217;s core philosophy is intact; it should still &#8220;feel like Mason&#8221; to existing users.</p>
<p>I&#8217;ve talked about plans for Mason 2 here <a href="http://www.openswartz.com/2009/09/01/what-mason-2-0-would-look-like/">before</a>, but as things have changed in the past year and a half, here&#8217;s an updated summary:</p>
<ul>
<li>
<p><strong>Name</strong>. The name is now Mason, instead of <a href="http://search.cpan.org/perldoc?HTML::Mason">HTML::Mason</a>.</p>
</li>
<li>
<p><strong>Component classes</strong>. Each component is represented by its own (Moose) class, rather than just an instance of a common class. This means that components have their own namespaces, subroutines, methods, and attributes, and can truly inherit from one other. See <a href="http://search.cpan.org/perldoc?Mason::Manual::Components">Mason::Manual::Components</a>.</p>
</li>
<li>
<p><strong>Filters</strong>. A single powerful filter syntax and mechanism consolidates three separate filter mechanisms from Mason 1 (filter blocks, components with content, and escape flags). See <a href="http://search.cpan.org/perldoc?Mason::Manual::Filters">Mason::Manual::Filters</a>.</p>
</li>
<li>
<p><strong>Plugins</strong>. Moose roles are utilized to create a flexible plugin system that can modify nearly every aspect of Mason&#8217;s operation. Previously core features such as caching can now be implemented in plugins. See <a href="http://search.cpan.org/perldoc?Mason::Manual::Plugins">Mason::Manual::Plugins</a>.</p>
</li>
<li>
<p><strong>Web integration</strong>. Mason 1&#8217;s bulky custom web handling code (<code>ApacheHandler</code>, <code>CGIHandler</code>) has been replaced with a simple <a href="http://search.cpan.org/perldoc?Mason::Plugin::PSGIHandler">PSGI handler</a> and with plugins for web frameworks like <a href="http://search.cpan.org/perldoc?Catalyst::View::Mason2">Catalyst</a> and <a href="http://search.cpan.org/perldoc?Dancer::Template::Mason2">Dancer</a>. The core Mason distribution is now completely web-agnostic. See <a href="http://search.cpan.org/perldoc?Mason::Plugin::PSGIHandler">Mason::Plugin::PSGIHandler</a>.</p>
</li>
<li>
<p><strong>File naming</strong>. Mason now facilitates and enforces (in a customizable way) standard file extensions for components: .m (top-level components), .mi (internal components), and .pm (pure-perl components).</p>
</li>
</ul>
<p>See <a href="http://search.cpan.org/perldoc?Mason::Manual::UpgradingFromMason1">Mason::Manual::UpgradingFromMason1</a> for a more detailed list of changes.</p>
<p>Mason 2 is obviously still in alpha status, but it has a fair sized test suite and I&#8217;m eager to start building web projects with it. I hope you&#8217;ll give it a try too! Post feedback here or on the <a href="https://lists.sourceforge.net/lists/listinfo/mason-users">Mason user&#8217;s list</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2011/02/21/announcing-mason-2/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Getting plugin-happy</title>
		<link>http://www.openswartz.com/2011/01/14/getting-plugin-happy/</link>
		<comments>http://www.openswartz.com/2011/01/14/getting-plugin-happy/#comments</comments>
		<pubDate>Fri, 14 Jan 2011 22:46:29 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=161</guid>
		<description><![CDATA[After converting Mason 2 to use Dist::Zilla and Pod::Weaver, I am starting to think in plugins and see opportunities for them everywhere.
As just one example, I initially added a cache feature to Mason 2, just because it was there in Mason 1 and seemed generally useful. But now I realize it can be cleanly separated [...]]]></description>
			<content:encoded><![CDATA[<p>After converting Mason 2 to use <a href="http://search.cpan.org/perldoc?Dist::Zilla">Dist::Zilla</a> and <a href="http://search.cpan.org/perldoc?Pod::Weaver">Pod::Weaver</a>, I am starting to think in plugins and see opportunities for them everywhere.</p>
<p>As just one example, I initially added a <em>cache</em> feature to Mason 2, just because it was there in Mason 1 and seemed generally useful. But now I realize it can be cleanly separated into <a href="https://github.com/jonswar/perl-mason/tree/master/lib/Mason/Plugin/Cache">its own plugin</a>.</p>
<p>There&#8217;s no real performance or footprint advantage for those that omit the plugin.  What it <strong>does</strong> do is put all the cache related code, documentation, and tests in a single place. As small as it is, the cache feature touched many of the main Mason modules in some way; now it is all in its own directory. It also makes me more amenable to expanding the feature (e.g. with new parameters or methods), because I&#8217;m not worried about disproportionately &#8220;polluting&#8221; the main code and API.</p>
<p>Of course, deciding what is a plugin versus a built-in feature (plus that third category, a plugin-in-name that really everyone expects to install) is the age-old question.  Too many plugins will of course hurt performance, because each one adds a layer of method modifiers, and will also hurt useability and readability. I&#8217;m still quite confused about where and how Dist::Zilla performs many of its tasks, and part of that is the sheer number of plugins one needs for a typical installation. It&#8217;s a virtual certainty that in my new enthusiasm I&#8217;ll over-plugin somewhere.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2011/01/14/getting-plugin-happy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mason 2: Filters</title>
		<link>http://www.openswartz.com/2010/12/27/mason-2-filters/</link>
		<comments>http://www.openswartz.com/2010/12/27/mason-2-filters/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 10:47:46 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=155</guid>
		<description><![CDATA[In Mason 1 there are several ways to filter content: the &#60;%filter&#62; section, escape flags, and Component Calls with Content. Each of these has their own disparate implementation and API.
In Mason 2 we aim to unify these with a single implementation and a more consistent syntax.
A set of standard filters are automatically available in components, [...]]]></description>
			<content:encoded><![CDATA[<p>In Mason 1 there are several ways to <em>filter</em> content: the <a href="http://www.masonhq.com/docs/manual/Devel.html#__filter__section">&lt;%filter&gt;</a> section, <a href="http://www.masonhq.com/docs/manual/Devel.html#escaping_expressions">escape flags</a>, and <a href="http://www.masonhq.com/docs/manual/Devel.html#component_calls_with_content">Component Calls with Content</a>. Each of these has their own disparate implementation and API.</p>
<p>In Mason 2 we aim to unify these with a single implementation and a more consistent syntax.</p>
<p>A set of <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Filters/Standard.pm">standard filters</a> are automatically available in components, and other filter packages can be loaded via <a href="http://www.openswartz.com/2010/12/14/mason-2-plugins/">plugins</a>.</p>
<h3><a name="block_invocation">Invoking filters (block syntax)</a></h3>
<p>Here&#8217;s the typical way of invoking a filter:</p>
<pre>
&lt;% $.Trim { %&gt;
This string will be trimmed
&lt;/%&gt;
</pre>
<p>Things to note here:</p>
<ul>
<li>An <code>{</code> at the end of a <code>&lt;% %&gt;</code> tag denotes a filter call.</li>
<li>The <code>&lt;/%&gt;</code> tag marks the end of the filtered content.</li>
<li>The expression <code>$.Trim</code>, aka <code>$self-&gt;Trim</code>, is a method call on the component object which returns a filter. In general everything before the brace is evaluated and is expected to return a filter or list of filters.</li>
<li>Filter names use <a href="http://c2.com/cgi/wiki?CamelCase">CamelCase</a> to distinguish themselves from other methods in the <code>Mason::Component</code> namespace. Another option was to use a standard prefix or suffix, e.g. <code>trim_filter</code> or <code>filter_trim</code>, but I thought this was the least ugly option and made filters look a little more like built-in tags.</li>
</ul>
<p>Filters can take arguments:</p>
<pre>
&lt;% $.Repeat(3) { %&gt;
  There's no place like home.
&lt;/%&gt;

  ==&gt;  There's no place like home.
 There's no place like home.
 There's no place like home.
</pre>
<p>Again, the expression <code>$.Repeat(3)</code> returns a filter, meaning that it can<br />
be curried:</p>
<pre>
% my $repeat_three = $.Repeat(3);
&lt;% $repeat_three { %&gt;
  There's no place like home.
&lt;/%&gt;
</pre>
<p>A simple filter is just a subroutine that takes text as input and return the<br />
new text. Thus you can create one-off filters with anonymous subroutines:</p>
<pre>
&lt;% sub { reverse($_[0]) } { %&gt;Hello&lt;/%&gt;

     ==&gt; olleH
</pre>
<p>Filters can be nested, with separate tags:</p>
<pre>
&lt;% $.Trim { %&gt;
  &lt;% sub { uc($_[0]) } { %&gt;
    This string will be trimmed and uppercased
  &lt;/%&gt;
&lt;/%&gt;
</pre>
<p>or within a single tag:</p>
<pre>
&lt;% $.Trim, sub { uc($_[0]) } { %&gt;
  This will be trimmed and uppercased
&lt;/%&gt;
</pre>
<p>Multiple filters within the same tag are applied, intuitively, in reverse order with the last one being innermost. e.g. in this block</p>
<pre>
% my $i = 1;
&lt;% $.Repeat(3), $.Cache($key, '1 hour') { %&gt; &lt;% $i++ %&gt; &lt;/%&gt;

  =&gt; 1 1 1
</pre>
<p>the output of <code>&lt;% $i++ %&gt;</code> is cached, and then repeated three times, whereas in this block</p>
<pre>
% my $i = 1;
&lt;% $.Cache($key, '1 hour'), $.Repeat(3) { %&gt; &lt;% $i++ %&gt; &lt;/%&gt;

  =&gt; 1 2 3
</pre>
<p><code>&lt;% $i++ %&gt;</code> is executed and output three times, and then the whole thing cached.</p>
<h4>Invoking filters (pipe syntax)</h4>
<p>Filters can also appear in a limited way inside a regular <code>&lt;% %&gt;</code> tag; this replaces Mason 1&#8217;s escape flags.</p>
<pre>
&lt;% $content | NoBlankLines,Trim %&gt;
</pre>
<p>The filter list contains one or more comma-separated names, which are treated as methods on the current component class. With this syntax you cannot use anonymous subroutines or variables as filters, or pass arguments to filters (but you can define local filter methods to get around this).</p>
<p>One common use of this form is to escape HTML strings:</p>
<pre>
&lt;% $message_body | H %&gt;
</pre>
<p>The <code>H</code> filter is provided along with other web-related filters in <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Plugin/HTMLFilters.pm">Mason::Plugin::HTMLFilters</a>.</p>
<h4>Applying filter to current component</h4>
<p>Mason 1&#8217;s <a href="http://www.masonhq.com/docs/manual/Devel.html#__filter__section">&lt;%filter&gt;</a> section was good for filtering the content of the current component. e.g. to make it uppercase:</p>
<pre>
&lt;%filter&gt;
$_ = uc($_);
&lt;/%filter&gt;
</pre>
<p>In Mason 2 the most succinct replacement is currently an <code>around</code> modifier:</p>
<pre>
&lt;%around main&gt;
&lt;% sub { uc($_[0]) } { %&gt;
% $self-&gt;$orig();
&lt;/%&gt;
&lt;/%around&gt;
</pre>
<h4>Creating filters</h4>
<p>Here&#8217;s a filter package that implements two filters, <code>Upper</code> and <code>Lower</code>:</p>
<pre>
package MyApp::Filters;
use Method::Signatures::Simple;
use Moose::Role;

method Upper () {
    return sub { uc($_[0]) }
}

method Lower () {
    return sub { lc($_[0]) }
}

1;
</pre>
<p>To use these in a component:</p>
<pre>
&lt;%class&gt;
with 'MyApp::Filters';
&lt;/%class&gt;

&lt;% $.Upper { %&gt;
...
&lt;/%&gt;
</pre>
<p>Or if you want them available to all components, put them in <code>Base.pm</code> at the top of your component hierarchy, or in your application&#8217;s <code>Mason::Component</code> subclass.</p>
<h4>Simple vs. dynamic filters</h4>
<p>A <em>simple filter</em> is a code ref which takes a string and returns the output, like <code>Upper</code> and <code>Lower</code> above.</p>
<p>A <em>dynamic filter</em> (a <code>Mason::DynamicFilter</code> object) contains a code ref which takes a <em>yield block</em> and returns the output. A yield block is a zero-argument code ref that returns a content string.</p>
<p>The power of dynamic filters is that they can choose if and when to execute the yield block. For example, here&#8217;s the standard <code>Cache</code> filter in action:</p>
<pre>
&lt;% $.Cache($key, '1 hour') { %&gt;
... some computed content ...
&lt;/%&gt;
</pre>
<p>This caches the inner content for one hour based on cache key <code>$key</code>. Here&#8217;s the implementation:</p>
<pre>
method Cache ( $key, $set_options ) {
    Mason::DynamicFilter-&gt;new(
        filter =&gt; sub {
            my $yield = shift;
            $self-&gt;cmeta-&gt;cache-&gt;compute( $key, $yield, $set_options );
        }
    );
}
</pre>
<p>Using CHI&#8217;s <a href="http://search.cpan.org/perldoc?CHI#Getting_and_setting">compute</a> method, we check the cache first and return the output immediately if it is available. Only on a cache miss do we actually execute the (presumably expensive) yield block. This could not be implemented with a simple filter since the content would be computed every time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2010/12/27/mason-2-filters/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>perltidy and &#8216;method&#8217;: happy together</title>
		<link>http://www.openswartz.com/2010/12/19/perltidy-and-method-happy-together/</link>
		<comments>http://www.openswartz.com/2010/12/19/perltidy-and-method-happy-together/#comments</comments>
		<pubDate>Sun, 19 Dec 2010 15:10:17 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=144</guid>
		<description><![CDATA[I wrote previously about the inability of perltidy to handle the method keyword of Method::Signatures::Simple. Now, Steve Hancock has graciously accepted my patches in the latest Perl::Tidy, including prefilter and postfilter options. This allows me to easily add method support:

Perl::Tidy::perltidy(
    ...,
    prefilter => sub {
     [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://www.openswartz.com/2010/11/26/another-method-signatures-simple-convert/">wrote previously</a> about the inability of perltidy to handle the <code>method</code> keyword of <a href="http://search.cpan.org/perldoc?Method::Signatures::Simple">Method::Signatures::Simple</a>. Now, Steve Hancock has graciously accepted my patches in the latest <a href="http://search.cpan.org/perldoc?Perl::Tidy">Perl::Tidy</a>, including prefilter and postfilter options. This allows me to easily add <code>method</code> support:</p>
<pre>
Perl::Tidy::perltidy(
    ...,
    prefilter => sub {
        $_ = $_[0];
        s/^method (.*)/sub $1 \#__METHOD/gm;
        return $_;
    },
    postfilter => sub {
        $_ = $_[0];
        s/^sub (.*?)\s* \#__METHOD/method $1/gm;
        return $_;
    }
);
</pre>
<ul>
<li>The prefilter code substitutes <code>method</code> for <code>sub</code>, and adds a comment<br />
so we&#8217;ll be able to find and convert these back afterwards.</li>
<li>When perltidy operates on the code, it will just see regular <code>sub</code>s and treat them accordingly.</li>
<li>The postfilter code converts the <code>sub</code> back to <code>method</code> wherever the special comment appears.
</ul>
<p>I put this in my private <a href="https://gist.github.com/747410">Perl::Tidy subclass</a>, along with other tweaks, such as telling perltidy to leave my Moose &#8216;has&#8217; lines alone (I prefer them to <b>always</b> be on one line).</p>
<p>Then I create my own perltidy script which uses this subclass:</p>
<pre>
#!/usr/local/bin/perl
package main;
use JS::Perl::Tidy;
JS::Perl::Tidy::perltidy();
</pre>
<p>A little messy, but it works. I&#8217;m a devoted perltidy user, with enforced perltidy-on-commit policy on every project, so I&#8217;m glad I don&#8217;t have to choose between perltidy and my favorite Perl tweaks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2010/12/19/perltidy-and-method-happy-together/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mason 2: Content wrapping</title>
		<link>http://www.openswartz.com/2010/12/15/mason-2-content-wrapping/</link>
		<comments>http://www.openswartz.com/2010/12/15/mason-2-content-wrapping/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 20:26:57 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=135</guid>
		<description><![CDATA[(These posts are starting to follow a familiar pattern: &#8220;In Mason 1 we did X, but in Mason 2, Moose makes it so much easier&#8230;)&#8221;
Anyway.
In Mason 1, content wrapping (the practice of wrapping HTML in one or more surrounding templates) was achieved via autohandlers. Each autohandler would print its content and then call $m-&#62;call_next, which [...]]]></description>
			<content:encoded><![CDATA[<p>(These posts are starting to follow a familiar pattern: &#8220;In Mason 1 we did X, but in Mason 2, Moose makes it so much easier&#8230;)&#8221;</p>
<p>Anyway.</p>
<p>In Mason 1, <em>content wrapping</em> (the practice of wrapping HTML in one or more surrounding templates) was achieved via <a href="http://search.cpan.org/perldoc?HTML::Mason::Devel#autohandlers">autohandlers</a>. Each autohandler would print its content and then call <a href="http://search.cpan.org/perldoc?HTML::Mason::Request#call_next"><code>$m-&gt;call_next</code></a>, which would pass control to the next component down the subclass chain. This was all special-purpose code written against Mason&#8217;s already hacky inheritance scheme.</p>
<p>But in <a href="https://github.com/jonswar/perl-mason">Mason 2</a>, Moose gives us a natural solution for this pattern: <a href="http://search.cpan.org/perldoc?Moose::Manual::MethodModifiers#INNER_AND_AUGMENT">inner and augment</a>.</p>
<p>At the start of a Mason 2 request, after determining the top-level component (aka &#8220;page component&#8221;), Mason will call that component&#8217;s <code>render()</code> method. By default, <code>render()</code> will just call <code>main()</code>, which outputs the main body of the component. However, each ancestor of the page component has an opportunity to wrap <code>render()</code> with its own template. For example:</p>
<pre># /Base.m - top-most template
#
&lt;%augment render&gt;
  &lt;html&gt;&lt;body&gt;
      &lt;% inner() %&gt;
      &lt;div class="footer"&gt;Copyright 2010 McHuffy Inc.&lt;/div&gt;
    &lt;/body&gt;&lt;/html&gt;
&lt;/%augment&gt;

# /product/Base.m - product-specific template
#
&lt;%augment render&gt;
  &lt;h2&gt;Products&lt;/h2&gt;
  &lt;&amp; product_nav.mi &amp;&gt;
  &lt;div class="products_body"&gt;
    &lt;% inner() %&gt;
  &lt;/div&gt;
&lt;/%augment&gt;

# /product/sales/Base.pm - utility methods, no additional template
#
&lt;%method some_utility_method&gt;
   ...
&lt;/%method&gt;

# /product/sales/display.m:
#
&lt;h3&gt;&lt;% $product-&gt;title %&gt;&lt;/h3&gt;
...</pre>
<p>The page /product/sales/display will be wrapped by two templates: the outer one<br />
in <tt>/Base.pm</tt>, and the inner one in <tt>/product/Base.pm</tt>.</p>
<p>A couple of new things here for Mason 1 users:</p>
<ul>
<li>&#8216;autohandler&#8217; has changed to &#8216;Base.m&#8217;. A component of this name becomes the automatic superclass of every component in its directory and subdirectories.</li>
<li>There are sections for declaring Moose methods and method modifiers with embedded-Perl syntax: <code>&lt;%after&gt;</code>, <code>&lt;%around&gt;</code>, <code>&lt;%augment&gt;</code>, <code>&lt;%before&gt;</code>, and <code>&lt;%method&gt;</code>. (Why we &#8220;need&#8221; all these explicit sections is a subject for another post.)</li>
</ul>
<p>Now here&#8217;s an implementation snag. Notice that neither <tt>/product/sales/display</tt> nor <tt>/product/sales/Base.pm</tt> have a render method. For the former, we want to automatically create a <code>render</code> that just calls <code>main</code>, which will display the main body of the component. For the latter, we want <code>render</code> to just fall through to the next level. But there&#8217;s no way to know in advance whether a component will be used as the page component or as one of its superclasses, so we have to create a default <code>render</code> for every component that does the right thing at runtime. In pseudo-code:</p>
<pre>if (we are a superclass of the page component) {
    # Go to the next level.
    inner();
} else {
    # We are the page component. Draw the main content.
    $self-&gt;main();
}</pre>
<p>Unfortunately there&#8217;s no official way to ask Moose whether we&#8217;re at the bottom of the inner() chain. So I&#8217;ve got a couple of choices here:</p>
<p>1. Check ref($self):</p>
<pre>if ( ref($self) ne __PACKAGE__ ) {
    inner();
} else {
    $self-&gt;main();
}</pre>
<p>As long as we provide a default render for every component, I think this should correctly distinguish the bottom of the chain. But I&#8217;m not entirely sure &#8211; Moose does a lot of with auto-generated subclasses.</p>
<p>2. Steal the code out of Moose::inner:</p>
<pre>if ( $Moose::INNER_BODY ) {
    inner();
} else {
    $self-&gt;main();
}</pre>
<p>Of course this is awful, as it relies on implementation details that are subject to change.</p>
<p>For now I&#8217;ll be going with #1.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2010/12/15/mason-2-content-wrapping/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mason 2: Plugins</title>
		<link>http://www.openswartz.com/2010/12/14/mason-2-plugins/</link>
		<comments>http://www.openswartz.com/2010/12/14/mason-2-plugins/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 15:12:53 +0000</pubDate>
		<dc:creator>Jonathan Swartz</dc:creator>
				<category><![CDATA[Mason 2]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.openswartz.com/?p=127</guid>
		<description><![CDATA[In Mason 1, extending Mason&#8217;s behavior means either using the limited plugin API (allowing you to take action before and after a request or component call), or else writing subclasses, which is problematic when you try to use more than one together.
In Mason 2, plugins are based on Moose roles, allowing you to modify behavior [...]]]></description>
			<content:encoded><![CDATA[<p>In Mason 1, extending Mason&#8217;s behavior means either using the <a href="http://cpan.uwinnipeg.ca/htdocs/HTML-Mason/HTML/Mason/Plugin.html">limited plugin API</a> (allowing you to take action before and after a request or component call), or else writing subclasses, which is problematic when you try to use more than one together.</p>
<p>In Mason 2, plugins are based on <a href="http://search.cpan.org/perldoc?Moose%3A%3AManual%3A%3ARoles">Moose roles</a>, allowing you to modify behavior in each of Mason&#8217;s main subclasses &#8212; <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Interp.pm">Interp</a>, <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Request.pm">Request</a>, <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Compiler.pm">Compiler</a>, <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Compilation.pm">Compilation</a>, and <a href="https://github.com/jonswar/perl-mason/blob/master/lib/Mason/Component.pm">Component</a> &#8212; in a composable way.</p>
<p>Here&#8217;s my first Mason 2 plugin, to perltidy object files after components are compiled &#8211; useful in development. First, a nominal base class:</p>
<pre>
package Mason::Plugin::TidyObjectFiles;
use Moose;
extends 'Mason::Plugin';

1;
</pre>
<p>(This has to exist for Mason to recognize the plugin, but there isn&#8217;t much to do there right now.)</p>
<p>Then, a role for each of Mason&#8217;s subclasses that we want to modify. In this case we only need to modify <code>Mason::Compiler</code>:</p>
<pre>
package Mason::Plugin::TidyObjectFiles::Compiler;
use Moose::Role;
use Perl::Tidy;
use strict;
use warnings;

has 'tidy_options' => ( is => 'ro' );

around 'write_object_file' => sub {
    my ( $orig, $self, $object_file, $object_contents ) = @_;

    my $argv = $self->tidy_options || '';
    my $source = $object_contents;
    Perl::Tidy::perltidy(
        'perltidyrc' => '/dev/null',
        source       => \$source,
        destination  => \$object_contents,
        argv         => $argv
    );
    $self->$orig( $object_file, $object_contents );
};

1;
</pre>
<p>To use this, I simply list &#8216;TidyObjectFiles&#8217; in my plugins:</p>
<pre>
my $mason = Mason->new(..., plugins=>[ 'TidyObjectFiles' ]);
</pre>
<p>or, if I want to specify perltidy options:</p>
<pre>
my $mason = Mason->new(..., plugins=>[ 'TidyObjectFiles' ], tidy_options => '-noll -l=100');
</pre>
<p>The <code>Mason::Plugin::</code> prefix is automatically added to plugin names. You can also specify a full path with a leading &#8216;+&#8217;, e.g.</p>
<pre>
plugins => ['+MyApp::Plugin::MyPlugin']
</pre>
<p>Now my object files go from looking like this:</p>
<pre>
no warnings 'redefine';
sub _comp_info { return {comp_dir_path => '/',comp_is_external => 1,comp_path => '/hi.m'} }
sub main {
my $self = shift;
my $m = $self->m;

my $_buffer = $m->current_buffer;
 #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
$$_buffer .= 'Hi there! The time is ';
 #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
{ $$_buffer .=  scalar(localtime)  if defined( scalar(localtime) ) }
 #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
$$_buffer .= '.
';

;return;
}
</pre>
<p>to this:</p>
<pre>
no warnings 'redefine';

sub _comp_info {
    return {
        comp_dir_path    => '/',
        comp_is_external => 1,
        comp_path        => '/hi.m'
    };
}

sub main {
    my $self = shift;
    my $m    = $self->m;

    my $_buffer = $m->current_buffer;

    #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
    $$_buffer .= 'Hi there! The time is ';

    #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
    { $$_buffer .= scalar(localtime) if defined( scalar(localtime) ) }

    #line 1 "/Users/swartz/git/mason.git/tmp/comps/hi.m"
    $$_buffer .= '.
';

    return;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.openswartz.com/2010/12/14/mason-2-plugins/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

