<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Mark A. Stratman</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/mark_a_stratman/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/mark_a_stratman//733</id>
    <updated>2011-04-14T16:05:28Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>RSS and Atom feeds in Catalyst</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/2011/04/rss-and-atom-feeds-in-catalyst.html" />
    <id>tag:blogs.perl.org,2011:/users/mark_a_stratman//733.1651</id>

    <published>2011-04-14T16:03:53Z</published>
    <updated>2011-04-14T16:05:28Z</updated>

    <summary>The Catalyst cookbook provides two recommendations for adding RSS feeds to your application: Create an XML template, populate the stash with data, let your template view render it, then override the Content-Type: header of your view with Catalyst::Response. Use an...</summary>
    <author>
        <name>Mark A. Stratman</name>
        
    </author>
    
    <category term="atom" label="atom" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="catalyst" label="catalyst" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rss" label="rss" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/mark_a_stratman/">
        <![CDATA[<p>The <a href="http://search.cpan.org/~zarquon/Catalyst-Manual/lib/Catalyst/Manual/Cookbook.pod#Adding_RSS_feeds">Catalyst cookbook</a> provides two recommendations for adding RSS feeds to your application:</p>
<ol>
	<li>Create an XML template, populate the stash with data, let your template view render it,  then override the <code>Content-Type:</code> header of your view with <a href="http://search.cpan.org/~bobtfish/Catalyst-Runtime/lib/Catalyst/Response.pm">Catalyst::Response</a>.</li>
        <li>Use an XML::* feed module to render the XML, manually set the Catalyst::Response body, then set the <code>Content-Type:</code> header.</li>
</ol>
<p>The former almost makes me angry, and the latter, although saner, puts view-specific responsibilities on the shoulders of the Controller.</p>
<h2>Catalyst::View::XML::Feed</h2>
<p><a href="http://search.cpan.org/~mstrat/Catalyst-View-XML-Feed/lib/Catalyst/View/XML/Feed.pm">Catalyst::View::XML::Feed</a> is an attempt at something cleaner, and more in the spirit of MVC, which makes the nitty-gritty details of presentation entirely the responsibility of the view.  Using it is pretty much what you would expect from any view:</p>
<ul>
    <li>Put your data in <code>$c-&gt;stash-&gt;{feed}</code></li>
    <li>Forward to your View::Feed (or whatever you called your Catalyst::View::XML::Feed subclass)</li>
</ul>
<p>It attempts to be as intelligent as possible, allowing you to supply data in <a href="http://search.cpan.org/~mstrat/Catalyst-View-XML-Feed/lib/Catalyst/View/XML/Feed.pm#DATA_FORMATS">a wide range of formats</a> to the <code>feed</code> value in the stash.  These can be XML::* Atom or RSS objects, custom objects, plain hashrefs of values, etc.
</p>
<p>As always, any recommendations or other feedback are warmly welcomed.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Syntax highlighting for search.cpan.org</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/2011/03/syntax-highlighting-for-searchcpanorg.html" />
    <id>tag:blogs.perl.org,2011:/users/mark_a_stratman//733.1585</id>

    <published>2011-03-24T02:14:56Z</published>
    <updated>2011-03-24T02:42:51Z</updated>

    <summary> If you&apos;re like me, you probably spend a lot of time looking at search.cpan.org. Occasionally I&apos;ll pull up perldoc directly in the terminal, but I love reading docs in the browser. I also love syntax highlighting. To some, it&apos;s...</summary>
    <author>
        <name>Mark A. Stratman</name>
        
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perldoc" label="perldoc" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="searchcpanorg" label="search.cpan.org" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="syntaxhighlighting" label="syntax highlighting" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/mark_a_stratman/">
        <![CDATA[<p>
If you're like me, you probably spend <em>a lot</em> of time looking at <a href="http://search.cpan.org">search.cpan.org</a>.  Occasionally I'll pull up <code>perldoc</code> directly in the terminal, but I love reading docs in the browser.
</p>
<p>I also love syntax highlighting.  To some, it's superfluous. To others, it's downright confusing.  But for those of us who use it all day every day, it's an essential tool that helps us read and understand code more quickly and with less effort.</p>
<p>It's always been a minor complaint that search.cpan.org does not put syntax highlighting on the perldocs.</p>
<p>Of course there are <a href="http://search.metacpan.org/">other sites</a> that do, but I'll confess to using Google most often to look up Perl modules.  And in the land of search results, search.cpan.org is king.</p>

<p>So without further ado, I'm happy to say that <a href="http://search.cpan.org">search.cpan.org</a> has syntax highlighting.   :)
If you scroll to the bottom of any rendered document, you will find a dropdown menu to choose your color scheme.  I recommend the "cpan" color scheme.</p>

<p>And if you hate syntax highlighting, don't get your panties in a bunch: "no syntax highlighting" is the default choice.</p>

<p>Many thanks to Graham Barr for his wonderful cooperation, accommodation, and help. And to the creators of <a href="http://shjs.sourceforge.net/">SHJS</a> and the <a href="https://github.com/mstratman/cpan-syntax">other tools</a> that make this possible.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Subclassing Tricky Non-Moose Classes: Constructor Problems</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-constructor-problems.html" />
    <id>tag:blogs.perl.org,2011:/users/mark_a_stratman//733.1524</id>

    <published>2011-03-09T21:43:18Z</published>
    <updated>2011-03-12T05:27:11Z</updated>

    <summary> We have a non-Moose class but want to make a Moose subclass of it. In the first post, &quot;Subclassing Tricky Non-Moose Classes: Don&apos;t Do It&quot;, we looked at a way to extend non-Moose classes without actually subclassing them. It...</summary>
    <author>
        <name>Mark A. Stratman</name>
        
    </author>
    
    <category term="moose" label="Moose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="moosexnonmoose" label="MooseX::NonMoose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="subclassing" label="subclassing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/mark_a_stratman/">
        <![CDATA[
<p>
We have a non-Moose class but want to make a Moose subclass of it.  In the first post, "<a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-dont-do-it.html">Subclassing Tricky Non-Moose Classes: Don't Do It</a>", we looked at a way to extend non-Moose classes without actually subclassing them.  It is pretty straight-forward, and typically will cause less headaches.
</p>

<p>Sometimes that method might not meet your needs, and you might <em>really</em> want to make a Moose subclass of a non-Moose class.  This tutorial will get you started with a couple modules that will help you do just that: <a href="http://search.cpan.org/~doy/MooseX-NonMoose/lib/MooseX/NonMoose.pm">MooseX::NonMoose</a> and <a href="http://search.cpan.org/~doy/MooseX-NonMoose/lib/MooseX/NonMoose/InsideOut.pm">MooseX::NonMoose::InsideOut</a>.
</p>

<h1>The nitty-gritty</h1>
<p>
If you're looking to get your hands dirty and find out how this really works, your first stop should be 
<a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Cookbook/Basics/Recipe11.pod">Recipe 11</a> in the <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Cookbook.pod">Moose Cookbook</a>.  It is optional reading for our purposes, though.
It does a great job explaining how to subclass a common, blessed hash, non-Moose class "by hand," and points us to MooseX::NonMoose which handles those details for us.
</p>

<p>We will take advantage of this handy module, and push forward to examine some trickier situations that can arise when subclassing non-Moose classes.</p>

<h1>1) The simplest case</h1>
<p>(Follow along with the <a href="https://gist.github.com/865259">example 1 gist</a>)</p>

<p>
In most circumstances using MooseX::NonMoose couldn't be easier.  Let's imagine we have this: <a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/10/Animal1.pm">Animal1.pm</a>.  It is a trivial example of an animal class, which takes a hash reference of attributes in the constructor like this 
<br />
<code>Animal1-&gt;new({ name =&gt; 'Lassie' })</code>
<br />
 and provides an accessor to <code>name</code> that allows us to set and get that attribute.
</p>

<p>In order to subclass this, all we need to do is add 
<br />
<code>use MooseX::NonMoose; extends 'Animal1';</code> 
<br />
  Let's do this to create a subclass called Camel with an additional attribute called <code>humps</code> to specify the number of humps on its back.  Our new class looks like this:
<a name="listing1"></a>
</p>

<pre>Camel example 1:
<code>package Camel;
use Moose;
use MooseX::NonMoose;
extends 'Animal1';

has 'humps' =&gt; ( is  =&gt; 'ro', isa =&gt; 'Num' );

no Moose;
__PACKAGE__-&gt;meta-&gt;make_immutable;</code></pre>

<p>We can now create a Camel object the same way we did with Animal1, but with the additional <code>humps</code> attribute.  Here is our example script:
<a name="listing2"></a>
</p>

<pre>Example script 1:
<code>#!/usr/bin/perl
use Modern::Perl;
use Camel;

my $c = Camel-&gt;new({ name =&gt; "Samuel Camel", humps =&gt; 2 });
say $c-&gt;name, " has ", $c-&gt;humps, " humps";</code></pre>

<p>This produces </p>
<pre><code>Samuel Camel has 2 humps</code></pre>

<p>
Most of the time subclassing a non-Moose class is as simple as this.  MooseX::NonMoose does all the work for us.
</p>

<h1>2) Incompatible constructors</h1>

<p>Sometimes, however, it isn't so easy.</p>

<p>What if our legacy class looked like this instead: <a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/10/Animal2.pm">Animal2.pm</a>.  It's largely the same as Animal1, except has a different constructor.  Instead of providing it with a hash reference of attributes, we simply pass it the animal's name: 
<br />
<code>Animal2-&gt;new("Lassie");</code>
</p>

<p>We'll use the exact same Camel subclass as in <a href="#listing1">Camel example 1</a>, just change "extends 'Animal1'" to "<em>extends 'Animal2'</em>".  Now let's try the <a href="#listing2">Example script</a> from above again.
</p>
<p>Oh dear.  This is not what we wanted...</p>
<pre><code>HASH(0x100803ee8) has 2 humps</code></pre>

<p>
Moose expects hash or hashref arguments passed to the constructor, but Animal2 wants a string.  Moose saw the first (and only) argument was a hashref, <code>{ name =&gt; "Samuel Camel", humps =&gt; 2 }</code>, as it expected, and stored the <code>name</code> attribute.   Animal2, on the other hand, does not accept hash references and simply tried to treat it as the animal's name (producing that "HASH(0x100...)").</p>

<p>
Let's look at two ways we can modify Camel to resolve this problem:
</p>
<ol>
  <li>accept a hash of attribute values in the constructor, breaking compatibility with Animal2</li>
  <li>accept a single argument in the constructor like Animal2</li>
</ol>

<br />

<a name="s_2_1"></a>
<h2>2.1) Resolving incompatible constructors - Using hashes</h2>
<p>(Follow along with the <a href="https://gist.github.com/865262">example 2.1 gist</a>)</p>

<p>Even though Animal2 doesn't support hashes passed into its constructor, we can modify Camel to allow it, enabling our <a href="#listing2">example script</a> from before to do what we wanted.</p>

<p>
We looked at <a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-dont-do-it.html#buildargs">BUILDARGS in our last tutorial</a>, which allows us to modify the arguments sent to the Moose constructor.  In this example, however, we need to modify the arguments sent to the Animal2 constructor.
</p>

<p>
MooseX::NonMoose provides a similar method, <a href="http://search.cpan.org/~doy/MooseX-NonMoose/lib/MooseX/NonMoose.pm#DESCRIPTION">FOREIGNBUILDARGS</a>, that allows us to determine what gets sent to the non-Moose parent constructor.  It works like this:
</p>
<pre><code># FOREIGNBUILDARGS is not declared anywhere in our parent classes,
# so we can just override it, rather than wrap it in 'around'
sub FOREIGNBUILDARGS {
    my $class = shift;
    # The remaining arguments were sent to the constructor.
    # e.g. if you called YourClass-&gt;new({ foo =&gt; 'bar' }), then 
    # @args contains one element, that hashref.
    my @args = @_;

    # ... Make any modifications to @args here.

    # Whatever we return will be sent to new() in the non-Moose parent
    return @args;
}</code></pre>

<p>Now take those principles and apply them to our problem in order to provide
the Animal2 constructor with a single string argument.</p>

<a name="listing3"></a>
<pre>Camel example 2.1:
<code>package Camel;
use Moose;
use MooseX::NonMoose;
extends 'Animal2';

has 'humps' =&gt; ( is  =&gt; 'ro', isa =&gt; 'Num' );

sub FOREIGNBUILDARGS {
    my $class = shift;
    # We expect a hashref with 'name' and 'humps'.
    my $args = shift;

    # Give Animal2 what it wants: just the name, and nothing else.
    return $args-&gt;{name};
}

no Moose;
__PACKAGE__-&gt;meta-&gt;make_immutable;</code></pre>

<h2>2.2) Resolving incompatible constructors - Maintaining compatibility with parent class</h2>

<p>(Follow along with the <a href="https://gist.github.com/865264">example 2.2 gist</a>)</p>

<p>NOTE: I do not recommend using this solution unless you must. Passing hashes to the constructor as we did in <a href="#s_2_1">solution in 2.1</a> results in more readable and maintainable code. That being said...</p>

<p>
If we want our Camel class to be a drop-in replacement for Animal2, we need the ability to pass our constructor just the name, rather than a hash.
But what about the number of humps? We could change the <code>humps</code> attribute to be read-write (<code>is =&gt; 'rw'</code> instead of 'ro') and create our object like this: <code>my $c = Camel-&gt;new("Samuel Camel"); $c-&gt;humps(2);</code>
</p>

<p>But this can be painful, especially when we're dealing with more complicated non-trivial classes. We probably prefer to leave <code>humps</code> readonly and instead pass the humps in the constructor like this: <code>Camel-&gt;new("Samuel Camel", 2);</code>
</p>

<p>Let's start back with the bare-bones <a href="#listing1">Camel example 1</a>, which does not mess with <code>BUILDARGS</code> or <code>FOREIGNBUILDARGS</code>.  If we try to use this with a constructor like this, <code>Camel-&gt;new("Samuel Camel");</code> we get the following error:
</p>
<pre><code>Single parameters to new() must be a HASH ref at...</code></pre>
<p>If you try to call <code>Camel-&gt;new("Samuel Camel", 2)</code> it won't throw an error, but it also will not store "2" for the number of humps. The Moose parent will interpret that as a hash <code>"Samuel Camel" =&gt; 2</code> with its "Samuel Camel" name being the key with the number of humps as the value.</p>

<p>In order to do this, <code>Camel-&gt;new("Samuel Camel", 2)</code> we need to intercept those arguments with <code>BUILDARGS</code> and give <code>{ humps =&gt; 2 }</code> to the Moose parent, and use <code>FOREIGNBUILDARGS</code> to  pass only the name "Samuel Camel" to the non-Moose parent.</p>

<p>
<a name="listing4"></a>
</p>

<pre>Camel example 2.2;
<code>package Camel;
use Moose;
use MooseX::NonMoose;
extends 'Animal2';

has 'humps' =&gt; ( is  =&gt; 'ro', isa =&gt; 'Num' );

# Make sure Moose::Object parent gets a hashref with 'humps' in it
around BUILDARGS =&gt; sub {
    my $orig  = shift;
    my $class = shift;
    # We expect this to be called with: Camel-&gt;new($name, $optional_humps)
    # so @_ contains a name, and possibly a number of humps.
    my $camel_name  = shift;
    my $camel_humps = shift;

    my $moose_args = {};
    $moose_args-&gt;{humps} = $camel_humps if defined $camel_humps;

    # Give Moose constructor what it wants
    return $class-&gt;$orig($moose_args);
};

# Make sure Animal2 parent only gets a name
sub FOREIGNBUILDARGS {
    my $class = shift;
    my $name = shift;
    my $humps = shift; # We are going to ignore this.

    # Whatever we return will be sent to Animal2-&gt;new()
    return $name;
}

no Moose;
__PACKAGE__-&gt;meta-&gt;make_immutable;</code></pre>

And now we have a drop-in replacement for Animal2 that can accept an optional second parameter in its constructor.  Here's how we can use it:

<pre>Example script 2.2:
<code>#!/usr/bin/perl
use Modern::Perl;
use Camel;

my $c = Camel-&gt;new("Samuel Camel", 2);
say $c-&gt;name, " has ", $c-&gt;humps, " humps";</code></pre>

<h1>3) Non-hash objects</h1>
<p>(Follow along with the <a href="https://gist.github.com/865272">example 3 gist</a>)</p>
<p>
For our final example, consider 
<a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/11/Animal3.pm">Animal3.pm</a> which is used exactly like Animal2, with a single string argument to its constructor: <code>Animal3-&gt;new("Lassie");</code>.  Take either of the Camel class examples we created for Animal2 (either the one whose constructor takes <a href="#listing3">hash-based arguments</a>, or <a href="#listing4">ordered arguments</a>). Be sure to change its <code>extends</code> to the new Animal3 class.
</p>
<p>If you try to use your new Camel class, you will get an error similar to this:
</p>
<pre><code>Not a HASH reference at generated method (unknown origin)...</code></pre>

<p>Most Perl classes use a
<a href="http://perldoc.perl.org/functions/bless.html">blessed</a> hash
<a href="http://perldoc.perl.org/perlobj.html#An-Object-is-Simply-a-Reference">behind the scenes</a>, and that is what MooseX::NonMoose expects.
</p>
<p>Even though Animal3 is used exactly like Animal2, this final example is implemented differenly inside.  It uses a blessed array instead of a hash. If this doesn't mean much to you yet, don't worry about it! We have a simple solution:
</p>
<p>In your Camel class, change the line that says <code>use MooseX::NonMoose;</code> to <code>use MooseX::NonMoose::InsideOut</code>.</p>
<p>When you encounter the "Not a HASH..." error while using MooseX::NonMoose, simply use MooseX::NonMoose:InsideOut instead.  That's it! Everything else we've learned about <code>BUILDARGS</code> and <code>FOREIGNBUILDARGS</code> still applies.</p>


<h1>Extra credit: Going the extra mile</h1>
<p>In <a href="#listing1">Camel example 1</a> and <a href="#listing3">Camel example 2.1</a>, we didn't utilize <code>BUILDARGS</code> for anything.  This means our Moose::Object constructor was getting exactly the arguments we were passing into Camel.  This includes the <code>name</code> attribute, which it has no knowledge of since it only exists in the non-Moose class.</p>
<p>To be a good citizen, we should probably strip out this <code>name</code> argument to keep it out of sight from our Moose parent.</p>
<p>Your mission, should you choose to accept it, is to add an <code>around BUILDARGS =&gt; sub { ... };</code> to clean up the arguments so they only include those newly-added, Moosified attributes (i.e. just <code>humps</code>).
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Subclassing Tricky Non-Moose Classes: Don&apos;t Do It</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-dont-do-it.html" />
    <id>tag:blogs.perl.org,2011:/users/mark_a_stratman//733.1521</id>

    <published>2011-03-04T02:55:41Z</published>
    <updated>2011-03-23T15:34:35Z</updated>

    <summary> We have a non-Moose class but want to make a Moose subclass of it. First, step back and consider if we really need a subclass. Don&apos;t subclass There are probably some good arguments against subclassing non-Moose classes with a...</summary>
    <author>
        <name>Mark A. Stratman</name>
        
    </author>
    
    <category term="moose" label="Moose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="moosexnonmoose" label="MooseX::NonMoose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="subclassing" label="subclassing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/mark_a_stratman/">
        <![CDATA[<p>
We have a non-Moose class but want to make a Moose subclass of it.
First, step back and consider if we <em>really</em> need a subclass.
</p>

<h1>Don't subclass</h1>
<p>There are probably some good arguments against subclassing non-Moose classes with a Moose class that center on principles of good design, and applying the most suitable design patterns.  From a practical standpoint, though, there's a very simple reason to avoid it:  using Moose to subclass a non-Moose class is fraught with "gotchas."  We'll see <a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-constructor-problems.html">some of these problems in an upcoming post</a>, but for now let's look at an alternative to subclassing.</p>

<p>Perhaps a better option is to simply create your a new class and use <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual/Delegation.pod">delegation</a> to call methods on an accessor containing your non-Moose object.
</p>
<p>Let's say we initially wanted to subclass <a href="http://search.cpan.org/~bbeausej/Date-Handler/Handler.pod">Date::Handler</a>, but we decided to try delegation instead.  After reading through <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual/Delegation.pod">Moose::Manual::Delegation</a> we come up with the following:</p>
<pre><code>package MyDate;
use Moose;
use namespace::autoclean;
use Date::Handler;

has 'date_handler' =&gt; (
    is =&gt; 'ro',
    isa =&gt; 'Date::Handler',
    handles =&gt; qr/.*/,
);</code></pre>

<p>
The <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose.pm#EXPORTED_FUNCTIONS">"handles" option</a> allows us to specify regular expressions, so rather than writing each of the countless methods Date::Handler provides, we simply specify that the <code>date_handler</code> attribute <code><strong>handles =&gt; qr/.*/</strong></code> .  Now our MyDate object will catch any method call and delegate it to the Date::Handler object in <code>date_handler</code>. In other words, instead of needing to write <code>$my_date->date_handler->date_handler_method()</code> we can write <code>$my_date->date_handler_method()</code>.
</p>

<p>There is still a major problem though. We initially wanted a subclass which, presumably, would act as a drop-in replacement.  Our new class fails at this because we need to set the <code>date_handler</code> attribute:
</p>
<pre><code>MyDate->new(date_handler => Date::Handler->new(\%date_handler_args));</code></pre>

<p>This is fairly inconvenient, and moreover, does not behave like a subclass would.</p>

<h1>A drop-in replacement</h1>
<a name="buildargs"></a>
<p>We need to tell our <code>MyDate->new(...)</code> method to take the same arguments as Date::Handler does.  Fortunately <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Object.pm">Moose::Object</a> provides a method called <code>BUILDARGS</code> that lets us modify the arguments sent to the constructor.  Overriding this <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual/BestPractices.pod#Always_call_the_original/parent_BUILDARGS">can be problematic</a> if we're not careful, so we'll use the <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual/MethodModifiers.pod#BEFORE,_AFTER,_AND_AROUND">around</a> method modifier to modify the arguments being sent to <code>BUILDARGS</code>.
</p>
<pre><code>around BUILDARGS =&gt; sub {
    my $orig = shift;
    my $class = shift;
    return $class->$orig(date_handler => Date::Handler-&gt;new(@_));
};</code></pre>

<p>When calling <code>$orig()</code> (i.e. <code>BUILDARGS</code>), we pass in the <code>date_handler</code> value automatically so the calling code no longer needs to worry about it.  Notice that we also DO NOT pass the value from <code>@_</code> to the constructor of our new MyDate class, but instead give it to the Date::Handler constructor.</p>

<p>We now have the ability to call <code>MyDate->new(\%date_handler_args)</code>, and otherwise treat this new class and its objects just as we would a Date::Handler.</p>

<p>Let's go ahead and add a leading underscore to the <code>_date_handler</code> attribute.  This isn't necessary, but it indicates that it is private and that the end-user should not worry about it.</p>

<h1>Decorating a non-Moose class</h1>

<p>
Putting it all together, we get the following (<a href="https://gist.github.com/865253">gist</a>).
</p>

<pre><code>package MyDate;
use Moose;
use namespace::autoclean;
use Date::Handler;

has '_date_handler' =&gt; (
    is =&gt; 'ro',
    isa =&gt; 'Date::Handler',
    handles =&gt; qr/.*/,
);
around BUILDARGS =&gt; sub {
    my $orig = shift;
    my $class = shift;
    return $class->$orig(_date_handler => Date::Handler-&gt;new(@_));
};

no Moose;
__PACKAGE__->meta->make_immutable;</code></pre>

<h1>But I REALLY want a subclass</h1>
<p>If you really want to make a Moose subclass of a non-Moose class, check out the following post where we cover <a href="http://blogs.perl.org/users/mark_a_stratman/2011/03/subclassing-tricky-non-moose-classes-constructor-problems.html">some examples of subclassing</a>.</p>

<h1>Credits</h1>
<p>
Thanks to doy, perigrin, and mst (and his mallet). 
I started writing some tutorials on subclassing tricky non-Moose classes, but they made the case that even if that's what you <em>want</em> to do, it's probably not what you <em>should</em> do.
</p>]]>
        
    </content>
</entry>

<entry>
    <title>The Future of Perl Documentation (part 1 of 3)</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/mark_a_stratman/2011/02/the-future-of-perl-documentation-part-1-of-3.html" />
    <id>tag:blogs.perl.org,2011:/users/mark_a_stratman//733.1497</id>

    <published>2011-02-28T22:48:21Z</published>
    <updated>2011-03-04T15:13:01Z</updated>

    <summary>Perceived Extinction - Some context Perl is tired, old, crusty, and ready for the farm where its spirit can run free with the likes of COBOL and Fortran. Or at least that&apos;s what some people outside the community say. We...</summary>
    <author>
        <name>Mark A. Stratman</name>
        
    </author>
    
    <category term="bigpicture" label="big picture" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="documentation" label="documentation" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perldoc" label="perldoc" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/mark_a_stratman/">
        <![CDATA[<h1>Perceived Extinction - <span style="font-style:italic;font-size:0.8em;">Some context</span></h1>

<p>
Perl is tired, old, crusty, and ready for the farm where its spirit can run free with the likes of COBOL and Fortran.
</p>

<p>
Or at least that's what some people outside the community say.
</p>

<p>
We know this couldn't be farther from the truth: <a href="http://www.activestate.com/blog/2010/04/perl-5-is-alive">Perl 5 is alive</a>, "<a href="http://modernperlbooks.com">Modern Perl</a>" is buzzing on everyone's lips, <a href="http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual.pod">Moose</a> has brought Perl OO into the 21st century, frameworks like <a href="http://wiki.catalystframework.org/wiki/">Catalyst</a> and <a href="http://mojolicio.us/">Mojolicious</a> tame monstrous web projects, and ORM libraries like <a href="http://search.cpan.org/~abraxxa/DBIx-Class/lib/DBIx/Class/Manual/DocMap.pod">DBIx::Class</a> make database interaction fun again!
</p>

<p>
A widely held view of Perl in the realm of large-scale software development, however, is that the language and community are dying. Despite the obvious absurdity of this to those of us in the Perl trenches every day, the perception of Perl can and will become self-fulfilling. Perception is -- or at least begets -- reality.  
</p>

<h2>The Future of Perl Documentation:</h2>
<ol>
  <li><strong>Perceived Extinction</strong> - <em>Some context</em></li>
  <li><a href="#"><strong>The Power of Shine, and Harnessing the Web</strong> (coming soon)</a> - <em>Arguments for rethinking documentation practices</em></li>
  <li><a href="#"><strong>An Evolution in Perl and CPAN Documentation</strong> (coming soon)</a> - <em>Proposal and RFC to reshape how we write documentation</em></li>
</ol>
<p>
This is the first of three posts where I will be discussing how a focus on revamping our documentation can help to revitalize and grow the Perl community.
</p>

<h2>The extinction of Perl? Aren't you taking this a bit far?</h2>
<p>
If your experiences have been to the contrary, that's great news! You should skip this post and move along to part 2. This first part merely serves as a backdrop on the stage - a bit of context to explain the story that follows. The changes I would like to propose in the following posts can be worth discussing no matter how strong the future of Perl might be.  
</p>

<p>
And while we are framing the argument, allow me to make something perfectly clear.  My experiences and frame of reference are primarily with Perl as a tool for large-scale software development.   
Aristotle Pagaltzis made a comment on the p5p list recently reminding us that <a href="http://www.nntp.perl.org/group/perl.perl5.porters/2011/02/msg169141.html">there are multiple strata in which Perl is used</a>.

It might be safe to say that people still, and increasingly turn to Perl in other strata, such as writing glue code, data munging utilities, one-off sysadmin scripts, and the like. Especially those tasks in which limited experience with large frameworks and best, modern practices are (arguably) lesser concerns. 
</p>

<p>That being said, let's turn our focus back to large-scale software development.</p>

<h2>Where is this coming from?</h2>

<p>
After 13 years of working with Perl, and the better part of a decade interviewing more developers for Perl jobs than I care to remember, I've noticed an alarming trend. The majority of people I've spoken with either: 
</p>
<ol>
    <li>haven't <em>had</em> the opportunity to use Perl for large projects due to constraints placed on them by their employers, or </li>
    <li>haven't <em>taken</em> the opportunity to use Perl for large projects because they view the language as one only suitable for small monolithic scripts and glue code.</li>
</ol>

<p>If you've ever conducted jobs interviews, you've likely run across countless candidates who fall into the first category. They once wrote a Perl script to convert a CSV file to XML, but "don't get to use Perl much" because every place they've worked has been a /java|ruby|python/c(?:\+\+)?/ shop.  
For each tool or technology you listed in the job posting, in addition to Perl, the number of these candidates increased exponentially.  They assumed $other_listed_tool was the primary development environment, and that Perl was merely required for occasional data munging.  In short, Perl is a tool that many use a little, and few use a lot.
</p>

<p>The latter category - those who undervalue Perl - is a little harder to spot in the wild if you're working mostly in Perl and hiring for such a position.  Who is going to be foolish enough to walk into an interview and deride the development team's chosen tool?  It happens, but is rare.  We recently had a gentleman come in and take every opportunity to preach the virtues of Ruby and Rails, and denigrate Perl as a "mess" and a "nightmare" for anything but small scripts.  This continued after he even admitted, when asked, he has no knowledge of Catalyst, Moose, or other modern tools and best practices.  This situation is rare though.
</p>
<p>Typically to find these Perl naysayers, you have to travel outside your immediate sphere of influence (unless you're already working in a role other than Perl development).  I spent 5 years working for a large university and interviewed a great many students looking for practical experience in various undergrad and graduate student jobs involving work on some large, OO Perl software. In all, I probably talked with between 100 and 150 students over the years (university student jobs have a high turnover).
</p>

<p>It did not take long to notice a trend.  Not only did the majority of students have no significant experience with Perl (which was expected), they had no desire to learn it and questioned the wisdom of choosing it for anything but the simplest of scripts. My own curiosity had me digging and probing with each of these encounters, especially after the umpteenth time hearing that backend systems should always be written in Java or C++, all modern web software should be done with Ruby and RoR, and other generalities that leave Perl by the wayside.</p>

<p>When pressed why they felt this way, a common reason emerged: <em>Perl is old, and fading fast</em>. These young, budding technologists had come under the impression that few people are making improvements in the Perl ecosystem. They worried it would be foolish to board a sinking ship, and that their time would be better spent with the shiny and trendy (Ruby) and the pillars of "enterprise" (Java and C++).</p>

<p>It was during this time that I started becoming increasingly concerned with the future of Perl, and began to seriously contemplate the power of perception.</p>

<h2>Perception begets reality</h2>
<p>
This is an admittedly subjective and highly experiential take on things, from my own little corner of the world.  For every each developer I have seen turn away from Perl, there may be only 1, or as many as 10,000 others. Either way it is a loss, it concerns me, and it should concern you.
</p>

<p>Each developer who chooses not to consider Perl as a serious contender for large-scale software development actually results in a bigger loss to the community.  Each loss contributes to the perception of a shrinking community, which in turn drives away even more potential Perl users.  The perception becomes self-fulfilling.
</p>

<p>
You might be asking "<em>why should I care?</em>"
 You use Perl.  You work with Perl. Your friends and coworkers use Perl.  None of this affects you.
</p>
<p>I push back on this assertion and challenge you to examine the bigger picture.  A growing negative perception of Perl, or worse, a shrinking a pool of Perl developers has two devastating consequences.
</p>
<p>
First, with each passing year there will be fewer and fewer experienced and highly qualified developers to hire. Empty seats on your team will remain vacant for longer, or will be filled with less qualified hires.
</p>
<p>
Second, and more importantly, as the perception of Perl as a tool for large-scale software development diminishes, so too do the number of companies and departments willing to undertake new development with it.  The opportunity to write in a great language, all day every day, dries up.
</p>

<p>Perhaps I am being too pessimistic, or putting undue weight on my own unique experiences. Perhaps my concerns are founded, but the time it takes for them to be realized will exceed the lifetime of Perl 5, and Perl 6 will renew and reinvigorate the community.  I concede that either or both of these may be the case.</p>
<p>Regardless, this is just context for my plan and proposal (part 3).  Whether or not you agree with my assessments, I hope you can agree to this:
</p>
<p><em>We need to correct the negative perceptions of Perl and attract more new developers to our community.</em>
</p>

<h2>What does this have to do with documentation?</h2>
<p>I believe there are two general ways to improve peoples' perceptions of Perl:</p>
<ul>
  <li>Active public relations</li>
  <li>Passive changes to the appearance of Perl and its community</li>
</ul>

<p>I see a lot of momentum in the public relations realm. Initiatives like <a href="http://mdk.per.ly/2011/02/25/i-need-your-help/">distributing Perl flyers</a> and the <a href="http://ironman.enlightenedperl.org/">Iron Man blogging challenge</a> (and countless others) can have some amazing results. I fully support these worthwhile efforts, and hope to jump in and help in whatever ways I can.</p>

<p>What I see lacking, though, and have begun investing significant time and effort into, is a similar renewal of documentation efforts - or the passive aspect of Perl's reinvigoration.  Looking at perldocs and perusing <a href="http://search.cpan.org">search.cpan.org</a> is how new (and even experienced) Perl programmers spend a sizable chunk of their time.  When somebody comes and sees Unix <code>man</code>-style API documentation with little context or explanation, finds few tie-ins between libraries, frameworks and modules, and has difficulties finding the answer to "how do I...." on CPAN, this leaves a bad taste.
</p>

<p>We have great documentation; Don't get me wrong.  And a wealth of it. But I think we can do better.  Much better.</p>

<p>I'll hash out specific ways our current documentation practices might be improved in Part 2, <a href="#">The Power of Shine, and Harnessing the Web (coming soon)</a>, and propose a possible new future for Perl and CPAN documentation in Part 3, <a href="#">An Evolution in Perl and CPAN Documentation (coming soon)</a>.
</p>]]>
        
    </content>
</entry>

</feed>
