<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Toby Inkster</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/toby_inkster/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/toby_inkster//1019</id>
    <updated>2013-05-06T13:22:37Z</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>Type::Tiny - not just for attributes</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/05/typetiny---not-just-for-attributes.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4650</id>

    <published>2013-05-06T13:15:29Z</published>
    <updated>2013-05-06T13:22:37Z</updated>

    <summary> OK, so I&apos;ve gotten back from the May Day parade, had some lunch, and now it&apos;s time for me to write about Type::Tiny some more......</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[		<p>OK, so I've gotten back from the May Day parade, had some lunch, and now it's time for me to write about Type::Tiny some more...</p>
]]>
        <![CDATA[		<p><a class="podlinkpod" href="https://metacpan.org/module/Type%3A%3ATiny">Type::Tiny</a> is a zero-dependency implementation of type constraints that can be used with <a class="podlinkpod" href="https://metacpan.org/module/Moose">Moose</a>, <a class="podlinkpod" href="https://metacpan.org/module/Mouse">Mouse</a> and <a class="podlinkpod" href="https://metacpan.org/module/Moo">Moo</a> alike. (No more need to build separate type libraries for each of them!)</p>
		<p>A typical usage might be:</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">package</span> <span class="word">Person</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Moose</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="word">-types</span><span class="structure">;</span>
        
        <span class="word">has</span> <span class="word">name</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span><span class="word">is</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">isa</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">Str</span><span class="structure">);</span>
        <span class="word">has</span> <span class="word">age</span>  <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span><span class="word">is</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">isa</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">Int</span><span class="structure">);</span></pre>
		<p>But why stop there? Type constraints can also be useful for other purposes such as unit testing (e.g. check your function returns an <code>Int</code>) and validation. It's validation we'll look at today; specifically validating sub parameters.</p>
		<p>Let's take a look at a simple function which takes a hash, and returns a copy of that hash, but adding a number to certain keys.</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="word">hash_add</span> <span class="structure">{</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$number</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$hash</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$keys</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="magic" style="color:#900;font-weight:bold">@_</span><span class="structure">;</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol" style="color:#333;background-color:#fcc">%clone</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="cast" style="color:#f00;font-weight:bold">%</span><span class="symbol" style="color:#333;background-color:#fcc">$hash</span><span class="structure">;</span>
                <span class="symbol" style="color:#333;background-color:#fcc">$clone</span><span class="structure">{</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">}</span> <span class="operator" style="color:#000;font-weight:bold">+=</span> <span class="symbol" style="color:#333;background-color:#fcc">$number</span> <span class="word">for</span> <span class="cast" style="color:#f00;font-weight:bold">@</span><span class="symbol" style="color:#333;background-color:#fcc">$keys</span><span class="structure">;</span>
                <span class="keyword" style="color:#009;font-weight:bold">return</span> <span class="cast" style="color:#f00;font-weight:bold">\</span><span class="symbol" style="color:#333;background-color:#fcc">%clone</span><span class="structure">;</span>
        <span class="structure">}</span>
        
        <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol" style="color:#333;background-color:#fcc">$r</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">hash_add</span><span class="structure">(</span><span class="number" style="color:#39C">7</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="structure">{</span> <span class="word">foo</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">bar</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">2</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">baz</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">3</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="structure">[</span><span class="words" style="color:#333;background-color:#ffc">qw/foo bar/</span><span class="structure">]);</span>
<span class="comment" style="color:#060;font-style:italic">        ## =&gt; { foo =&gt; 8, bar =&gt; 9, baz =&gt; 3 }</span></pre>
		<p>Why would you want a function like this? I admit it's somewhat contrived, but it includes three different types (a number, a hashref and an arrayref), so is a good illustration of the principles involved.</p>
		<p>Here's how you'd add parameter validation using the venerable <a class="podlinkpod" href="https://metacpan.org/module/Params%3A%3AValidate">Params::Validate</a>:</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Params::Validate</span> <span class="words" style="color:#333;background-color:#ffc">qw(:all)</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Scalar::Util</span> <span class="words" style="color:#333;background-color:#ffc">qw(looks_like_number)</span><span class="structure">;</span>
        
        <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="word">hash_add</span> <span class="structure">{</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$number</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$hash</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$keys</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">validate_pos</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">@_</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                        <span class="structure">{</span>
                                <span class="word">type</span>      <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">SCALAR</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                                <span class="word">callbacks</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span> <span class="word">numeric</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="structure">{</span> <span class="word">looks_like_number</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">[</span><span class="number" style="color:#39C">0</span><span class="structure">])</span> <span class="structure">}</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                        <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                        <span class="structure">{</span> <span class="word">type</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">HASHREF</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                        <span class="structure">{</span> <span class="word">type</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">ARRAYREF</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
                <span class="structure">);</span>
                <span class="operator" style="color:#000;font-weight:bold">...</span><span class="structure">;</span>
        <span class="structure">}</span></pre>
		<p>Using <a class="podlinkpod" href="https://metacpan.org/module/Type%3A%3AParams">Type::Params</a> which comes bundled with Type::Tiny is somewhat more elegant for this simple case (which is not to say that it is always so!):</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Type::Params</span> <span class="words" style="color:#333;background-color:#ffc">qw(compile)</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="word">-types</span><span class="structure">;</span>
        
        <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="word">hash_add</span> <span class="structure">{</span>
                <span class="word">state</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">compile</span><span class="structure">(</span><span class="word">Num</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">HashRef</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">ArrayRef</span><span class="structure">);</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$number</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$hash</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$keys</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">@_</span><span class="structure">);</span>
                <span class="operator" style="color:#000;font-weight:bold">...</span><span class="structure">;</span>
        <span class="structure">}</span></pre>
		<p>But surely this elegance comes at some cost? After all; Params::Validate is fast! It has an XS backend that blows the socks off many of its rivals (<a class="podlinkpod" href="https://metacpan.org/module/Data%3A%3AValidator">Data::Validator</a>, etc).</p>
		<p>Well, you'd be wrong! According to my benchmarks, Type::Params is more than twice as fast as Params::Validate's XS backend. (And more than six times as fast as Params::Validate's pure Perl backend.) Don't believe me? <a class="podlinkurl" href="https://gist.github.com/tobyink/5501883">Here is my benchmark script</a>.</p>
		<p>In fact, Type::Params is so fast, and building up constraints is so simple, that you might find yourself wanting to make your validation more brutal, just because you can! Let's make sure that all the values in the hashref are really numbers; and that all the elements of the arrayref are strings:</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="word">hash_add</span> <span class="structure">{</span>
                <span class="word">state</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">compile</span><span class="structure">(</span><span class="word">Num</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">HashRef</span><span class="structure">[</span><span class="word">Num</span><span class="structure">]</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">ArrayRef</span><span class="structure">[</span><span class="word">Str</span><span class="structure">]);</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$number</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$hash</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$keys</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">@_</span><span class="structure">);</span>
                <span class="operator" style="color:#000;font-weight:bold">...</span><span class="structure">;</span>
        <span class="structure">}</span></pre>
		<p>OK, so this is slower than our earlier parameter check, but not unacceptably slow; and still faster than the <i>less strict</i> Params::Validate check.</p>
		<h2><span id="How??">How??</span></h2>
		<p>So, how does Type::Params achieve its speed? Super optimized assembly language programming linked to via XS? Nothing of the sort; it's actually pure Perl.</p>
		<p>It's fast because the first time you call <code>hash_add</code>, it generates a long string of Perl code that will be used to validate your parameters, then passes that through <code>eval</code> to create a custom validation coderef for your sub. (Just a glimpse of the mess of source code within that coderef is enough to give many people nightmares!) This first call is actually far slower than Params::Validate - about 10 times slower than the PP backend, but that's still under a millisecond on most modern computers.</p>
		<p>Subsequent calls to the same function reuse that coderef, so go much faster.</p>
		<p>The break-even point for using this trick seems to be around 20 sub calls. If your sub is going to be called more than 20 times, compiling that coderef is a sound investment. (If your sub is going to be called fewer times, then you probably don't need to worry too much about micro-optimizing parameter validation anyway.)</p>
		<p>This is similar to what <a class="podlinkpod" href="https://metacpan.org/module/Moose">Moose</a> does when you run:</p>
		<pre class="highlighting-perl">        <span class="word">__PACKAGE__</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">meta</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">make_immutable</span><span class="structure">;</span></pre>
		<p>... and it's used all over the place within the Type-Tiny distribution.</p>
		<h2><span id="What_else_should_I_know?">What else should I know?</span></h2>
		<p>Type::Params is not a drop-in replacement for Params::Validate. Their features overlap, but are not identical.</p>
		<p>Params::Validate allows you to supply defaults for missing parameters; Type::Params does not. Params::Validate has a more natural interface for validating named parameters than Type::Params (though Type::Params can still do this). Each of them currently require Perl 5.8.1 or above, but CPAN still has old versions of Params::Validate available for Perl 5.5.</p>
		<p>Type::Params automatically does coercion (including "deep coercions") if your type constraint has coercions defined:</p>
		<pre class="highlighting-perl">        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Type::Params</span> <span class="words" style="color:#333;background-color:#ffc">qw(compile)</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Type::Utils</span> <span class="words" style="color:#333;background-color:#ffc">qw(declare as coerce from via)</span><span class="structure">;</span>
        <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="words" style="color:#333;background-color:#ffc">qw(:types slurpy)</span><span class="structure">;</span>
        
        <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol" style="color:#333;background-color:#fcc">$Rounded</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">declare</span> <span class="word">as</span> <span class="word">Int</span><span class="structure">;</span>
        <span class="word">coerce</span> <span class="symbol" style="color:#333;background-color:#fcc">$Rounded</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">from</span> <span class="word">Num</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">via</span> <span class="structure">{</span> <span class="word">int</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">)</span> <span class="structure">};</span>
        
        <span class="keyword" style="color:#009;font-weight:bold">sub</span> <span class="word">numbers</span> <span class="structure">{</span>
                <span class="word">state</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">compile</span><span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$Rounded</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">slurpy</span> <span class="word">ArrayRef</span><span class="structure">[</span><span class="symbol" style="color:#333;background-color:#fcc">$Rounded</span><span class="structure">]);</span>
                <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$first</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol" style="color:#333;background-color:#fcc">$rest</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="symbol" style="color:#333;background-color:#fcc">$check</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">@_</span><span class="structure">);</span>
                
<span class="comment" style="color:#060;font-style:italic">                # $first is 1
                # $rest is [2, 3]
</span>        <span class="structure">}</span>
        
        <span class="word">numbers</span><span class="structure">(</span><span class="float">1.1</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="float">2.2</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="float">3.3</span><span class="structure">);</span></pre>
		<p>But for me, ultimately the most compelling reason to use Type::Params is that it allows you to use the same library of type constraints for sub parameter validation that you already use for attributes in Moose/Moo/Mouse OO code.</p>
]]>
    </content>
</entry>

<entry>
    <title>Thought for the day: Perl 5 is English; Perl 6 is Esperanto.</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/04/thought-for-the-day-perl-5-is-english-perl-6-is-esperanto.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4591</id>

    <published>2013-04-19T23:04:27Z</published>
    <updated>2013-04-19T23:21:24Z</updated>

    <summary>Esperanto may be a saner language than English in every way. But English is the language of Shakespeare, of Milton, of Byron, of Dylan Thomas; the language of Arthur Conan-Doyle and Agatha Christie; the language of Tolkien and C S...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>Esperanto may be a saner language than English in every way.</p>

<p>But English is the language of Shakespeare, of Milton, of Byron, of Dylan Thomas; the language of Arthur Conan-Doyle and Agatha Christie; the language of Tolkien and C S Lewis; of Lewis Carroll and Beatrix Potter. It's the language of Stoker and Shelley.</p>

<p>Wikipedia notes that <a href="http://en.wikipedia.org/wiki/Esperanto_literature">over 100 original novels have been published in Esperanto</a>. Big woop-dee-doo(!)</p>

<p>I want to be able to use Perl 6 day to day, but not if that involves missing out on Perl 5's literature (i.e. <span class="caps">CPAN</span>).</p>]]>
        
    </content>
</entry>

<entry>
    <title>Introducing Type::Tiny</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/04/introducing-typetiny.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4574</id>

    <published>2013-04-15T13:30:00Z</published>
    <updated>2013-04-15T13:00:03Z</updated>

    <summary> Type::Tiny is a tiny (no non-core dependencies) framework for building type constraints. OK, probably not that exciting. How can I grab your attention? Rate WithMoose WithMooseAndTypeTiny WithMoose 8071/s -- -25% WithMooseAndTypeTiny 10778/s 34% -- The benchmark script is shown...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="Type-Tiny" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[		<p><a class="podlinkpod" href="https://metacpan.org/module/Type%3A%3ATiny">Type::Tiny</a> is a tiny (no non-core dependencies) framework for building type constraints. OK, probably not that exciting. How can I grab your attention?</p>
		<!-- for highlighter language=Text -->
		<pre class="highlighting-text">                         Rate            WithMoose WithMooseAndTypeTiny
 WithMoose             8071/s                   --                 -25%
 WithMooseAndTypeTiny 10778/s                  34%                   --</pre>
		<!-- for highlighter language=Perl -->
		<p>The benchmark script is shown later so you can check I'm not doing anything hideously unfair to disadvantage Moose.</p>
		<p>How can I <i>hold</i> your attention?</p>
]]>
        <![CDATA[		<p><b>Type constraint libraries built with Type::Tiny work with Moose, Mouse <i>and</i> Moo!</b> And because it's such a lightweight framework, with no dependencies on heavy metaobject protocols, it even becomes appealing to use in situations where you might not otherwise consider using a type constraint library at all.</p>
		<p>Type::Tiny comes bundled with a number of other modules that help round out the framework, including:</p>
		<ul>
			<li><a class="podlinkpod" href="https://metacpan.org/module/Type%3A%3ALibrary">Type::Library</a> - a base class for collections of type constraints</li>
			<li><a class="podlinkpod" href="https://metacpan.org/module/Type%3A%3AUtils">Type::Utils</a> - syntactic sugar for declaring types</li>
			<li><a class="podlinkpod" href="https://metacpan.org/module/Types%3A%3AStandard">Types::Standard</a> - a library of commonly used types</li>
			<li><a class="podlinkpod" href="https://metacpan.org/module/Test%3A%3ATypeTiny">Test::TypeTiny</a> - simple functions for testing type constraints work</li>
		</ul>
		<h2><span id="Type_Constraints?">Type Constraints?</span></h2>
		<p>Let's get back to basics... what's a type constraint library? If you're writing anything more than a quick throwaway script, you generally need to do a bit of data validation. Your <code>array_sum</code> function might need to check that it gets passed an arrayref and all the values in the array are numeric.</p>
		<p>In another part of the code your <code>delete_articles_by_id</code> function might also need to accept an array of numeric values. Two checks for arrayrefs of numbers, in different parts of your codebase. The principle of <a class="podlinkurl" href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> says that you should factor both of these checks out to a single place in your code.</p>
		<p>Once you've factored all of these checks out into one place, that's your type constraint library.</p>
		<h2><span id="Building_a_Type_Library_with_Type::Library">Building a Type Library with Type::Library</span></h2>
		<p>Let's say we want to build a "natural numbers" type constraint. Natural numbers are the positive integers plus zero. (The inclusion of zero is contentious in some circles, but we'll put that aside for now.) It helps that <a class="podlinkpod" href="https://metacpan.org/module/Types%3A%3AStandard">Types::Standard</a> defines an <code>Int</code> type constraint, so rather than starting from scratch, we can refine that.</p>
		<pre class="highlighting-perl"> <span class="keyword" style="color:#009;font-weight:bold">package</span> <span class="word">MyApp::Types</span><span class="structure">;</span>
 
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">base</span> <span class="double" style="color:#909">"Type::Library"</span><span class="structure">;</span>  <span class="comment" style="color:#060;font-style:italic"># type libraries must inherit from this</span>
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Type::Utils</span><span class="structure">;</span>           <span class="comment" style="color:#060;font-style:italic"># sugar for declaring type constraints</span>
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="words" style="color:#333;background-color:#ffc">qw(Int)</span><span class="structure">;</span>
 
 <span class="word">declare</span> <span class="double" style="color:#909">"NaturalNum"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">as</span> <span class="word">Int</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">where</span> <span class="structure">{</span> <span class="magic" style="color:#900;font-weight:bold">$_</span> <span class="operator" style="color:#000;font-weight:bold">&gt;=</span> <span class="number" style="color:#39C">0</span> <span class="structure">};</span>
 
 <span class="number" style="color:#39C">1</span><span class="structure">;</span>  <span class="comment" style="color:#060;font-style:italic"># magic true value</span></pre>
		<p>That was easy. Now within our application we can:</p>
		<pre class="highlighting-perl"> <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">MyApp::Types</span> <span class="words" style="color:#333;background-color:#ffc">qw(NaturalNum)</span><span class="structure">;</span></pre>
		<p>And this will export <code>NaturalNum</code> as a "constant". The constant returns an object that we can call methods on, so:</p>
		<pre class="highlighting-perl"> <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">check</span><span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$value</span><span class="structure">);</span>         <span class="comment" style="color:#060;font-style:italic"># returns true or false</span>
 <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">assert_valid</span><span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$value</span><span class="structure">);</span>  <span class="comment" style="color:#060;font-style:italic"># returns true or dies</span></pre>
		<p>The constant can also be used directly within <a class="podlinkpod" href="https://metacpan.org/module/Moo">Moo</a> or <a class="podlinkpod" href="https://metacpan.org/module/Moose">Moose</a> attribute declarations:</p>
		<pre class="highlighting-perl"> <span class="word">has</span> <span class="word">message_count</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span><span class="word">is</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">isa</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">required</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="structure">);</span></pre>
		<h2><span id="Coercions">Coercions</span></h2>
		<p>A next step is to define coercions. Within our type constraint library we can add:</p>
		<pre class="highlighting-perl"> <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="words" style="color:#333;background-color:#ffc">qw( Num ArrayRef )</span><span class="structure">;</span>
 
 <span class="word">coerce</span> <span class="double" style="color:#909">"NaturalNum"</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">from</span> <span class="word">Num</span><span class="operator" style="color:#000;font-weight:bold">,</span>      <span class="word">via</span> <span class="structure">{</span> <span class="word">int</span><span class="structure">(</span><span class="word">abs</span><span class="structure">(</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">))</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">from</span> <span class="word">ArrayRef</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">via</span> <span class="structure">{</span> <span class="word">scalar</span><span class="structure">(</span><span class="cast" style="color:#f00;font-weight:bold">@</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">)</span> <span class="structure">};</span></pre>
		<p>Now within our application we can:</p>
		<pre class="highlighting-perl"> <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">MyApp::Types</span> <span class="words" style="color:#333;background-color:#ffc">qw(to_NaturalNum)</span><span class="structure">;</span>
 
 <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol" style="color:#333;background-color:#fcc">$goats</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="structure">[</span><span class="double" style="color:#909">"Alice Gruff"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="double" style="color:#909">"Bob Gruff"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="double" style="color:#909">"Carol Gruff"</span><span class="structure">];</span>
 <span class="word">say</span> <span class="word">to_NaturalNum</span><span class="structure">(</span><span class="symbol" style="color:#333;background-color:#fcc">$goats</span><span class="structure">);</span>  <span class="comment" style="color:#060;font-style:italic"># say 3</span></pre>
		<p>Coercions can be used within Moose attribute definitions:</p>
		<pre class="highlighting-perl"> <span class="word">has</span> <span class="word">message_count</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span>
    <span class="word">is</span>       <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">isa</span>      <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">required</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">coerce</span>   <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span>
 <span class="structure">);</span></pre>
		<p>Or Moo attribute definitions:</p>
		<pre class="highlighting-perl"> <span class="word">has</span> <span class="word">message_count</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span>
    <span class="word">is</span>       <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">isa</span>      <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">required</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">coerce</span>   <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">NaturalNum</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">coercion</span><span class="operator" style="color:#000;font-weight:bold">,</span>  <span class="comment" style="color:#060;font-style:italic"># spot the difference</span>
 <span class="structure">);</span></pre>
		<p>Coercions are a useful feature, and there are planned additions to Type::Coercion and Type::Library to make them even better in the future.</p>
		<p>* * *</p>
		<p>Anyway, I hope this provides a brief summary of Type::Tiny's features, and maybe tempts you to try it out. Keep an eye out for future articles on topics such as optimizing type constraints, and coercion power features.</p>
		<h2><span id="Appendix">Appendix</span></h2>
		<p>Here's the benchmarking script as promised...</p>
		<pre class="highlighting-perl"> <span class="keyword" style="color:#009;font-weight:bold">package</span> <span class="word">main</span><span class="structure">;</span>
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">strict</span><span class="structure">;</span>
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">warnings</span><span class="structure">;</span>
 <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Benchmark</span> <span class="words" style="color:#333;background-color:#ffc">qw(cmpthese)</span><span class="structure">;</span>
 
 <span class="structure">{</span>
    <span class="keyword" style="color:#009;font-weight:bold">package</span> <span class="word">Class::WithMoose</span><span class="structure">;</span>
    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Moose</span><span class="structure">;</span>
    <span class="word">has</span> <span class="word">attr</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span><span class="word">is</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">isa</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ArrayRef[Int]"</span><span class="structure">);</span>
    <span class="word">__PACKAGE__</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">meta</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">make_immutable</span><span class="structure">;</span>
 <span class="structure">}</span>
 
 <span class="structure">{</span>
    <span class="keyword" style="color:#009;font-weight:bold">package</span> <span class="word">Class::WithMooseAndTypeTiny</span><span class="structure">;</span>
    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Moose</span><span class="structure">;</span>
    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">Types::Standard</span> <span class="word">-all</span><span class="structure">;</span>
    <span class="word">has</span> <span class="word">attr</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">(</span><span class="word">is</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"ro"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">isa</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">ArrayRef</span><span class="structure">[</span><span class="word">Int</span><span class="structure">]);</span>
    <span class="word">__PACKAGE__</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">meta</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">make_immutable</span><span class="structure">;</span>
 <span class="structure">}</span>
 
 <span class="keyword" style="color:#009;font-weight:bold">our</span> <span class="symbol" style="color:#333;background-color:#fcc">%data</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="structure">(</span> <span class="word">attr</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">[</span><span class="number" style="color:#39C">1</span> <span class="operator" style="color:#000;font-weight:bold">..</span> <span class="number" style="color:#39C">20</span><span class="structure">]</span> <span class="structure">);</span>
 
 <span class="word">cmpthese</span><span class="structure">(</span><span class="number" style="color:#39C">-1</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="structure">{</span>
    <span class="word">WithMoose</span>            <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="literal" style="color:#909">q{ Class::WithMoose-&gt;new(%::data) }</span><span class="operator" style="color:#000;font-weight:bold">,</span>
    <span class="word">WithMooseAndTypeTiny</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="literal" style="color:#909">q{ Class::WithMooseAndTypeTiny-&gt;new(%::data) }</span><span class="operator" style="color:#000;font-weight:bold">,</span>
 <span class="structure">});</span></pre>
]]>
    </content>
</entry>

<entry>
    <title>Introducing Platform</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/03/introducing-platform.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4431</id>

    <published>2013-03-14T16:30:16Z</published>
    <updated>2013-03-14T16:09:49Z</updated>

    <summary> So, what&apos;s the big idea? Perl projects have all manner of ways of declaring their dependencies. CPAN releases usually include a file called META.yml or META.json listing their dependencies (though Makefile.PL or Build.PL is also supposed to generate a...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[		<h2><span id="So,_what's_the_big_idea?">So, what's the big idea?</span></h2>
		<p>Perl projects have all manner of ways of declaring their dependencies. CPAN releases usually include a file called META.yml or META.json listing their dependencies (though Makefile.PL or Build.PL is also supposed to generate a list of dependencies when it runs; this allows the release to dynamically decide on different dependencies based on the machine it's running on). Non-CPAN projects can declare their CPAN dependencies using <a class="podlinkpod" href="https://metacpan.org/module/Module::CPANfile">cpanfile</a> too.</p>
		<p>Once the dependencies are declared, this information is used by CPAN clients, by metacpan.org (to show the list of a release's dependencies), by <a class="podlinkurl" href="http://deps.cpantesters.org/">http://deps.cpantesters.org/</a> and so on.</p>
		<p>However, this only works where you want to declare dependencies on CPAN modules, or on a minimum version of Perl itself.</p>
]]>
        <![CDATA[		<p>There's another few important types of dependency - your project may depend on external libraries or binaries, or may depend on a particular platform (e.g. code that only works, or only makes sense to use on Windows).</p>
		<p>For external libraries, there is good work going on in the Alien namespace on CPAN. And it seems reasonable to extend this approach to binaries.</p>
		<p>For platforms, the solution to this has often been to include code in Makefile.PL to check <code>$^O</code> looks OK and die otherwise:</p>
		<pre>        <span class="word">die</span> <span class="double" style="color:#909">"Windows only!"</span> <span class="word">unless</span> <span class="magic" style="color:#900;font-weight:bold">$^O</span> <span class="operator" style="color:#000;font-weight:bold">eq</span> <span class="double" style="color:#909">"MSWin32"</span><span class="structure">;</span></pre>
		<p>However, this approach doesn't leave any indication of the required platform in META.yml; it's invisible to services performing automated analysis of CPAN; metacpan.org's dependency listings won't show it.</p>
		<p>The Platform namespace is designed as a solution to these issues.</p>
		<h2><span id="What_is_in_the_Platform_namespace?">What is in the Platform namespace?</span></h2>
		<p>Initially three releases. The first is <a class="podlinkpod" href="https://metacpan.org/module/Platform">Platform</a> itself - a documentation-only release explaining the concept.</p>
		<p>The next is <a class="podlinkpod" href="https://metacpan.org/module/Platform%3A%3AUnix">Platform::Unix</a>. This is a module that doesn't "do" anything, but will only install and only run on Unix-like platforms. So if your Perl project requires a Unix-like OS, just add a dependency on Platform::Unix, and Bob's your uncle. Having Platform::Unix listed in your META.yml and on your metacpan.org page makes it really explicit to your users that your release requires a Unix-like operating system.</p>
		<p>The third release is <a class="podlinkpod" href="https://metacpan.org/module/Platform%3A%3AWindows">Platform::Windows</a> which is much the same thing for Windows.</p>
		<h2><span id="Any_more_planned?">Any more planned?</span></h2>
		<p>No, but if you have any requests, let me know. I've got a template for building new Platform releases in <a class="podlinkurl" href="https://bitbucket.org/tobyink/p5-platform">the Platform repository</a>.</p>
]]>
    </content>
</entry>

<entry>
    <title>Not using that any more...</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/03/not-using-that-any-more.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4394</id>

    <published>2013-03-04T22:26:33Z</published>
    <updated>2013-03-04T22:41:30Z</updated>

    <summary>OK, so sometimes you decide you&apos;re going to stop using some module X, maybe because something better has come along. Let&apos;s say I want to track down all my CPAN modules that use Any::Moose because my goal is to port...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="MetaCPAN" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>OK,
so sometimes you decide you're going to stop using some module X,
maybe because something better has come along.
Let's say I want to track down all my CPAN modules that use <a href="https://metacpan.org/module/Any%3A%3AMoose" class="podlinkpod">Any::Moose</a> because my goal is to port each of them to either <a href="https://metacpan.org/module/Moose" class="podlinkpod">Moose</a> or <a href="https://metacpan.org/module/Moo" class="podlinkpod">Moo</a>.</p>

<p>MetaCPAN has all the dependency information,
but I don't want to click through each of my distributions.
Enter the MetaCPAN API...</p>
]]>
        <![CDATA[<pre><span class="line_number" style="color:#666"> 1: </span><span class="comment" style="color:#060;font-style:italic">   #!/usr/bin/env perl
</span><span class="line_number" style="color:#666"> 2: </span>   
<span class="line_number" style="color:#666"> 3: </span>   <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="version">v5.10</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 4: </span>   <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">strict</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 5: </span>   <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">warnings</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 6: </span>   
<span class="line_number" style="color:#666"> 7: </span>   <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">HTTP::Tiny</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 8: </span>   <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">JSON</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 9: </span>   
<span class="line_number" style="color:#666">10: </span>   <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">@fields</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="words" style="color:#333;background-color:#ffc">qw&lt; distribution version date &gt;</span><span class="structure">;</span>
<span class="line_number" style="color:#666">11: </span>   
<span class="line_number" style="color:#666">12: </span>   <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="structure">(</span><span class="symbol">$module</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol">$author</span><span class="structure">)</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="symbol">@ARGV</span><span class="structure">;</span>
<span class="line_number" style="color:#666">13: </span>   <span class="symbol">$module</span> <span class="operator" style="color:#000;font-weight:bold">or</span> <span class="word">die</span> <span class="double" style="color:#909">"usage: $0 MODULE [AUTHOR]\n"</span><span class="structure">;</span>
<span class="line_number" style="color:#666">14: </span>   
<span class="line_number" style="color:#666">15: </span>   <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">$query</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="structure">{</span>
<span class="line_number" style="color:#666">16: </span>      <span class="word">size</span>   <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">5000</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">17: </span>      <span class="word">fields</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="cast" style="color:#f00;font-weight:bold">\</span><span class="symbol">@fields</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">18: </span>      <span class="word">query</span>  <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span> <span class="word">match_all</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{}</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">19: </span>      <span class="word">filter</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span>
<span class="line_number" style="color:#666">20: </span>         <span class="word">and</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">[</span>
<span class="line_number" style="color:#666">21: </span>            <span class="structure">{</span> <span class="word">term</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span> <span class="double" style="color:#909">"release.dependency.module"</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="symbol">$module</span> <span class="structure">}</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">22: </span>            <span class="structure">{</span> <span class="word">term</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span> <span class="double" style="color:#909">"release.status"</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"latest"</span><span class="structure">}</span> <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">23: </span>         <span class="structure">]</span>
<span class="line_number" style="color:#666">24: </span>      <span class="structure">}</span>
<span class="line_number" style="color:#666">25: </span>   <span class="structure">};</span>
<span class="line_number" style="color:#666">26: </span>   
<span class="line_number" style="color:#666">27: </span>   <span class="word">push</span> <span class="cast" style="color:#f00;font-weight:bold">@</span><span class="structure">{</span><span class="symbol">$query</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">{</span><span class="word">filter</span><span class="structure">}{</span><span class="word">and</span><span class="structure">}}</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="structure">{</span> <span class="word">term</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span> <span class="double" style="color:#909">"release.author"</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="symbol">$author</span> <span class="structure">}</span> <span class="structure">}</span>
<span class="line_number" style="color:#666">28: </span>      <span class="word">if</span> <span class="symbol">$author</span><span class="structure">;</span>
<span class="line_number" style="color:#666">29: </span>   
<span class="line_number" style="color:#666">30: </span>   <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">$response</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="double" style="color:#909">"HTTP::Tiny"</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">new</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">post</span><span class="structure">(</span>
<span class="line_number" style="color:#666">31: </span>      <span class="double" style="color:#909">"http://api.metacpan.org/v0/release/_search"</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span>
<span class="line_number" style="color:#666">32: </span>         <span class="word">content</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="word">to_json</span><span class="structure">(</span><span class="symbol">$query</span><span class="structure">)</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">33: </span>         <span class="word">headers</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span>
<span class="line_number" style="color:#666">34: </span>            <span class="double" style="color:#909">"Content-Type"</span> <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="double" style="color:#909">"application/json"</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">35: </span>         <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">36: </span>      <span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">37: </span>   <span class="structure">);</span>
<span class="line_number" style="color:#666">38: </span>   
<span class="line_number" style="color:#666">39: </span>   <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">$result</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="word">from_json</span><span class="structure">(</span><span class="symbol">$response</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">{</span><span class="word">content</span><span class="structure">});</span>
<span class="line_number" style="color:#666">40: </span>   
<span class="line_number" style="color:#666">41: </span>   <span class="keyword" style="color:#009;font-weight:bold">for</span> <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">$dist</span> <span class="structure">(</span><span class="cast" style="color:#f00;font-weight:bold">@</span><span class="structure">{</span> <span class="symbol">$result</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">{</span><span class="word">hits</span><span class="structure">}{</span><span class="word">hits</span><span class="structure">}</span> <span class="structure">})</span> <span class="structure">{</span>
<span class="line_number" style="color:#666">42: </span>      <span class="word">printf</span><span class="structure">(</span><span class="double" style="color:#909">"%s\t%s\t%s\n"</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="word">map</span> <span class="symbol">$dist</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="structure">{</span><span class="word">fields</span><span class="structure">}{</span><span class="magic" style="color:#900;font-weight:bold">$_</span><span class="structure">}</span><span class="operator" style="color:#000;font-weight:bold">,</span> <span class="symbol">@fields</span><span class="structure">);</span>
<span class="line_number" style="color:#666">43: </span>   <span class="structure">}</span></pre>

]]>
    </content>
</entry>

<entry>
    <title>Pod to HTML</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/02/pod-to-html.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4383</id>

    <published>2013-02-26T20:54:33Z</published>
    <updated>2013-02-27T11:37:18Z</updated>

    <summary> OK, so there were already a thousand solutions for converting pod to HTML, but I wasn&apos;t especially happy with any of them. Things I wanted were: Clean-looking XHTML and/or HTML5 output. Unicode support. ☻ Good syntax highlighting for Perl...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="pod" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[		<p>OK, so there were already <a class="podlinkurl" href="https://metacpan.org/search?q=pod+html">a thousand solutions</a> for converting pod to HTML, but I wasn't especially happy with any of them. Things I wanted were:</p>
		<ul>
			<li>Clean-looking XHTML and/or HTML5 output.</li>
			<li>Unicode support. ☻</li>
			<li>Good syntax highlighting for Perl code samples within the pod.</li>
			<li>Links to <a class="podlinkurl" href="https://metacpan.org/">metacpan.org</a> by default rather than <a class="podlinkurl" href="http://search.cpan.org/">search.cpan.org</a>.</li>
		</ul>
		<p>And so I've cobbled together a solution using <a class="podlinkpod" href="https://metacpan.org/module/Pod%3A%3ASimple">Pod::Simple</a>, <a class="podlinkpod" href="https://metacpan.org/module/PPI%3A%3AHTML">PPI::HTML</a>, <a class="podlinkpod" href="https://metacpan.org/module/HTML%3A%3AHTML5%3A%3AParser">HTML::HTML5::Parser</a>, <a class="podlinkpod" href="https://metacpan.org/module/HTML%3A%3AHTML5%3A%3AWriter">HTML::HTML5::Writer</a>, <a class="podlinkpod" href="https://metacpan.org/module/XML%3A%3ALibXML%3A%3APrettyPrint">XML::LibXML::PrettyPrint</a> and <a class="podlinkpod" href="https://metacpan.org/module/Moo">Moo</a>, and released it as <a class="podlinkpod" href="https://metacpan.org/module/TOBYINK%3A%3APod%3A%3AHTML">TOBYINK::Pod::HTML</a>.</p>
]]>
        <![CDATA[		<p>Here's the example from the synopsis section:</p>
		<pre><span class="line_number" style="color:#666"> 1: </span><span class="comment" style="color:#060;font-style:italic">    #!/usr/bin/perl
</span><span class="line_number" style="color:#666"> 2: </span>    
<span class="line_number" style="color:#666"> 3: </span>    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">strict</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 4: </span>    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="pragma" style="color:#009">warnings</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 5: </span>    <span class="keyword" style="color:#009;font-weight:bold">use</span> <span class="word">TOBYINK::Pod::HTML</span><span class="structure">;</span>
<span class="line_number" style="color:#666"> 6: </span>    
<span class="line_number" style="color:#666"> 7: </span>    <span class="keyword" style="color:#009;font-weight:bold">my</span> <span class="symbol">$pod2html</span> <span class="operator" style="color:#000;font-weight:bold">=</span> <span class="double" style="color:#909">"TOBYINK::Pod::HTML"</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">new</span><span class="structure">(</span>
<span class="line_number" style="color:#666"> 8: </span>        <span class="word">pretty</span>             <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span>       <span class="comment" style="color:#060;font-style:italic"># nicely indented HTML</span>
<span class="line_number" style="color:#666"> 9: </span>        <span class="word">code_highlighting</span>  <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="number" style="color:#39C">1</span><span class="operator" style="color:#000;font-weight:bold">,</span>       <span class="comment" style="color:#060;font-style:italic"># use PPI::HTML</span>
<span class="line_number" style="color:#666">10: </span>        <span class="word">code_line_numbers</span>  <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="core" style="color:#009;font-weight:bold">undef</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">11: </span>        <span class="word">code_styles</span>        <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="structure">{</span>        <span class="comment" style="color:#060;font-style:italic"># some CSS</span>
<span class="line_number" style="color:#666">12: </span>            <span class="word">comment</span>   <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="single" style="color:#909">'color:green'</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">13: </span>            <span class="word">keyword</span>   <span class="operator" style="color:#000;font-weight:bold">=&gt;</span> <span class="single" style="color:#909">'font-weight:bold'</span><span class="operator" style="color:#000;font-weight:bold">,</span>
<span class="line_number" style="color:#666">14: </span>        <span class="structure">}</span>
<span class="line_number" style="color:#666">15: </span>    <span class="structure">);</span>
<span class="line_number" style="color:#666">16: </span>    
<span class="line_number" style="color:#666">17: </span>    <span class="word">print</span> <span class="symbol">$pod2html</span><span class="operator" style="color:#000;font-weight:bold">-&gt;</span><span class="word">file_to_html</span><span class="structure">(</span><span class="word">__FILE__</span><span class="structure">);</span></pre>
		<p>There's a basic command-line script <code>pod2html-tobyink</code> supplied with it.</p>
		<p>Oh, and this blog post was <a class="podlinkurl" href="https://bitbucket.org/tobyink/p5-tobyink-pod-html/src/tip/devel.docs/blog/2013-02-26.pod">written as pod</a> and <a class="podlinkurl" href="https://bitbucket.org/tobyink/p5-tobyink-pod-html/src/tip/devel.docs/blog/2013-02-26.html">converted to HTML</a>.</p>
]]>
    </content>
</entry>

<entry>
    <title>Perl 10</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/02/perl-10.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4289</id>

    <published>2013-02-08T22:44:04Z</published>
    <updated>2013-02-08T23:01:55Z</updated>

    <summary>This is my take on the version debate. Bear in mind that I&apos;m not a p5p nor a Perl 6 developer, so I don&apos;t get a vote. I can still have an opinion though... Perl 6 represents the future of...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="future" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>This is my take on the version debate. Bear in mind that I'm not a p5p nor a Perl 6 developer, so I don't get a vote. I can still have an opinion though...</p>

<p>Perl 6 represents the future of Perl. But given the amount of time taken to get to where it is today, and the amount of work still needed before it can be put forward as a serious replacement for Perl 5, it realistically represents the <strong>distant</strong> future of Perl.</p>]]>
        <![CDATA[<p>Perl 6 should stop squatting on the major version "6" until it gets its act together, and rebrand as something funky and mystical sounding like "Black Perl".</p>

<p>Once what is now known as Perl 6 has a different name, it gives p5p the freedom to release Perl 6, Perl 7, Perl 8, etc. They don't have to - and none of the stuff coming up in 5.18 would justify a major version bump - but they'd have the choice.</p>

<p><span class="caps">P5P </span>should cautiously adopt features from Black Perl (or whatever it's called) where they can be done without disrupting existing Perl 5 syntax too much, much like has already happened with <code>say</code>, the defined-or operator, etc.</p>

<p>Once Black Perl is a serious contender to replace p5p's Perls in terms of performance, stability and the ability to run the majority of <span class="caps">CPAN </span>code (which would be helped by the p5p Perls adopting Black Perl features, and thus <span class="caps">CPAN </span>slowly becoming more Black Perlish), then it would replace the existing codebase and become the official Perl 9 or Perl 10 or whatever.</p>]]>
    </content>
</entry>

<entry>
    <title>Windows CPAN Testers, your help please...</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/01/windows-cpan-testers-your-help-please.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4217</id>

    <published>2013-01-21T09:38:06Z</published>
    <updated>2013-01-21T10:40:43Z</updated>

    <summary>I recently blogged about Ask, my new(ish) module for interacting with users via STDIN/STDOUT, a GUI, or whatever means possible. Writing GUI code in Perl unfortunately requires you to compile non-core modules such as Gtk2, Wx or Tk. There is...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="Windows" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>I recently <a href="http://blogs.perl.org/users/toby_inkster/2013/01/ask-not-what-your-user-can-do-for-you.html">blogged about Ask</a>, my new(ish) module for interacting with users via STDIN/STDOUT, a GUI, or whatever means possible.</p>

<p>Writing GUI code in Perl unfortunately requires you to compile non-core modules such as Gtk2, Wx or Tk. There is an alternative no-compilation-required approach though: most modern Linux and BSD distributions ship with (or at least package for separate download) a program called <a href="http://enwp.org/Zenity">Zenity</a>. Zenity is a tool for adding basic GUI dialogue boxes to shell scripts. You call it like this:</p>

<pre>
zenity --file-selection
</pre>

<p>And it will display a standard file chooser. Once a file is chosen, Zenity will print the file path to STDOUT and then exit.</p>

<p>Ask provides Ask::Zenity, a wrapper around Zenity, and will fall back to that if Wx, Gtk2, Tk, etc are not available. However, none of this really addresses Windows...</p>]]>
        <![CDATA[<p>So I've dug out an old copy of VB.NET and written a Zenity-like tool for Windows, called <a href="https://bitbucket.org/tobyink/vb-wenity">Wenity</a> (I know, great name). Its functionality is mostly a subset of Zenity.</p>

<p>Wenity is now on CPAN as <a href="http://search.cpan.org/~tobyink/Alien-Wenity-0.000_01/">Alien-Wenity 0.000_01</a>. I'd appreciate some Windows users testing this distribution to see how easy/successful it is to install.</p>]]>
    </content>
</entry>

<entry>
    <title>Ask not what your user can do for you...</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/01/ask-not-what-your-user-can-do-for-you.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4214</id>

    <published>2013-01-18T20:49:48Z</published>
    <updated>2013-01-18T21:31:31Z</updated>

    <summary>In many scripts, we need to prompt the end user for information - this could be a prompt for a file name, a selection from a list of options, or an answer to a yes/no question. The traditional approach to...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>In many scripts,
we need to prompt the end user for information - this could be a prompt for a file name,
a selection from a list of options,
or an answer to a yes/no question.</p>

<p>The traditional approach to this sort of question is to print your question to STDOUT,
read a line from STDIN,
and apply some sort of parsing to the answer...</p>

<pre>   <b>use</b> <span style="color:#00007f">5.010</span>;
   <b>use</b> <b>strict</b>;
   <b>use</b> <b>warnings</b>;
   
   <b>my</b> <span style="color:#0000ff">$answer</span>;
   <b>until</b> (<span style="color:#007f00">defined</span> <span style="color:#0000ff">$answer</span>) {
      <span style="color:#007f00">print</span> <span style="color:#ffa500">"</span><span style="color:#ff0000">Would you like fries with that?</span><span style="color:#ff00ff">\n</span><span style="color:#ffa500">"</span>;
      <span style="color:#0000ff"><b>$_</b></span> = &lt;&gt;;
      <span style="color:#0000ff">$answer</span> = <span style="color:#00007f">1</span> <b>if</b> <span style="color:#ffa500">/</span><span style="color:#ff00ff">^</span><span style="color:#b03060">Y</span><span style="color:#ffa500">/i</span>;
      <span style="color:#0000ff">$answer</span> = 0 <b>if</b> <span style="color:#ffa500">/</span><span style="color:#ff00ff">^</span><span style="color:#b03060">N</span><span style="color:#ffa500">/i</span>;
   }
   
   <b>say</b> <span style="color:#ffa500">"</span><span style="color:#ff0000">Adding fries!</span><span style="color:#ffa500">"</span> <b>if</b> <span style="color:#0000ff">$answer</span>;</pre>

<p>One issue with this approach is: what happens when your script is not running in a terminal?</p>
]]>
        <![CDATA[<p>One attempt at solving this problem is <a href="https://metacpan.org/module/IO::Prompt::Tiny" class="podlinkpod">IO::Prompt::Tiny</a> and its ilk. This performs a simple test to determine if the script is running on an interactive terminal and only prompts the user if the terminal is interactive. When the script is being run non-interactively (or if the <code>PERL_MM_USE_DEFAULT</code> environment variable is set), then it returns a default answer instead.</p>

<pre>   <b>use</b> <span style="color:#00007f">5.010</span>;
   <b>use</b> <b>strict</b>;
   <b>use</b> <b>warnings</b>;
   <b>use</b> <span style="color:#007f00">IO::Prompt</span>::<span style="color:#007f00">Tiny</span> <span style="color:#ffa500">qw(</span>prompt<span style="color:#ffa500">)</span>;
   
   <b>my</b> <span style="color:#0000ff">$answer</span>;
   <b>until</b> (<span style="color:#007f00">defined</span> <span style="color:#0000ff">$answer</span>) {
      <span style="color:#7f7f7f"><i># In non-interactive mode, assume they want no fries...</i></span><span style="color:#7f7f7f"><i>
</i></span>      <span style="color:#0000ff"><b>$_</b></span> = prompt(<span style="color:#ffa500">"</span><span style="color:#ff0000">Would you like fries with that?</span><span style="color:#ffa500">"</span>, <span style="color:#ffa500">"</span><span style="color:#ff0000">No</span><span style="color:#ffa500">"</span>);
      <span style="color:#0000ff">$answer</span> = <span style="color:#00007f">1</span> <b>if</b> <span style="color:#ffa500">/</span><span style="color:#ff00ff">^</span><span style="color:#b03060">Y</span><span style="color:#ffa500">/i</span>;
      <span style="color:#0000ff">$answer</span> = 0 <b>if</b> <span style="color:#ffa500">/</span><span style="color:#ff00ff">^</span><span style="color:#b03060">N</span><span style="color:#ffa500">/i</span>;
   }
   
   <b>say</b> <span style="color:#ffa500">"</span><span style="color:#ff0000">Adding fries!</span><span style="color:#ffa500">"</span> <b>if</b> <span style="color:#0000ff">$answer</span>;</pre>

<p>The problem with this is that it makes the assumption that when the terminal is non-interactive, there is absolutely no other way to prompt the user, and you should be happy with the default answer. This is not always a good assumption.</p>

<h2><span>Opening up a dialogue</span></h2>

<p>On some operating systems, double-clicking a Perl file will launch it without a terminal. In these cases, you can probably interact with the user by launching a dialog box. But how to do that? Doesn't that require complex programming in <a href="https://metacpan.org/module/Tk" class="podlinkpod">Tk</a> or <a href="https://metacpan.org/module/Wx" class="podlinkpod">Wx</a> (modules which are not in core, and not always straightforward to build)?</p>

<p>Enter <a href="https://metacpan.org/module/Ask" class="podlinkpod">Ask</a>. Ask abstracts away the details of interacting with your user. It will do the terminal interaction test; it will check <code>PERL_MM_USE_DEFAULT</code>; it will see if the <a href="https://metacpan.org/module/Wx" class="podlinkpod">Wx</a>, <a href="https://metacpan.org/module/Gtk2" class="podlinkpod">Gtk2</a> or <a href="https://metacpan.org/module/Tk" class="podlinkpod">Tk</a> modules are installed and usable; it will even use <code>/usr/bin/zenity</code> (a GNOME component for adding GUI dialog boxes to shell scripts) if it has to.</p>

<p>It will only resort to using the default answer if there's no other possibility of interacting with the user. Here's our fast food worker using Ask:</p>

<pre>   <b>use</b> <span style="color:#00007f">5.010</span>;
   <b>use</b> <b>strict</b>;
   <b>use</b> <b>warnings</b>;
   <b>use</b> Ask <span style="color:#ffa500">qw(</span>question<span style="color:#ffa500">)</span>;
   
   <b>my</b> <span style="color:#0000ff">$answer</span> = question(<span style="color:#ffa500">"</span><span style="color:#ff0000">Would you like fries with that?</span><span style="color:#ffa500">"</span>, default =&gt; 0);
   <b>say</b> <span style="color:#ffa500">"</span><span style="color:#ff0000">Adding fries!</span><span style="color:#ffa500">"</span> <b>if</b> <span style="color:#0000ff">$answer</span>;</pre>

<h2><span>That is the question</span></h2>

<p>In the previous example, we saw a yes-no question. How about something a bit harder?</p>

<pre>   <b>use</b> Ask <span style="color:#ffa500">qw(</span> multiple_choice <span style="color:#ffa500">)</span>;
   
   <b>my</b> <span style="color:#0000ff">@answers</span> = multiple_choice(
      <span style="color:#ffa500">"</span><span style="color:#ff0000">Please choose some pizza toppings...</span><span style="color:#ffa500">"</span>,
      choices =&gt; [
         [ sauce        =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Our famous pizza sauce</span><span style="color:#ffa500">'</span> ],
         [ cheese       =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Oozing Mozzarella cheese</span><span style="color:#ffa500">'</span> ],
         [ ham          =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Finest Bavarian ham</span><span style="color:#ffa500">'</span> ],
         [ pepperoni    =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Spicy pepperoni</span><span style="color:#ffa500">'</span> ],
         [ onion        =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Onion slices</span><span style="color:#ffa500">'</span> ],
         [ tinned_fruit =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">Chunky cuts of fresh pineapple</span><span style="color:#ffa500">'</span> ],
      ],
   );
   <b>say</b> <span style="color:#ffa500">"</span><span style="color:#ff0000">Adding </span><span style="color:#0000ff"><b>$_</b></span><span style="color:#ffa500">"</span> <b>for</b> <span style="color:#0000ff">@answers</span>;</pre>

<p>Or if you just wish them to choose a single option from a list:</p>

<pre>   <b>use</b> Ask <span style="color:#ffa500">qw(</span> single_choice <span style="color:#ffa500">)</span>;
   
   <b>my</b> <span style="color:#0000ff">$existance</span> = single_choice(
      <span style="color:#ffa500">"</span><span style="color:#ff0000">To be, or not to be; that is the question.</span><span style="color:#ffa500">"</span>,
      choices =&gt; [
         [ be     =&gt; <span style="color:#ffa500">"</span><span style="color:#ff0000">Be</span><span style="color:#ffa500">"</span> ],
         [ not_be =&gt; <span style="color:#ffa500">"</span><span style="color:#ff0000">Don't be</span><span style="color:#ffa500">"</span> ],
      ],
   );</pre>

<p>Ask also has functions for file selection, text entry (including hidden text - passwords) and displaying information, warnings and errors.</p>

<h2><span>I object!</span></h2>

<p>If you object to using the functional interface, you can get an object using the <code>Ask-&gt;detect</code> method and call <code>question</code>, <code>single_choice</code> and friends as object methods.</p>

<pre>   <b>use</b> <span style="color:#00007f">5.010</span>;
   <b>use</b> <b>strict</b>;
   <b>use</b> <b>warnings</b>;
   <b>use</b> Ask;
   
   <b>my</b> <span style="color:#0000ff">$interface</span> = Ask-&gt;detect;
   
   <b>my</b> <span style="color:#0000ff">$answer</span> = <span style="color:#0000ff">$interface</span>-&gt;<span style="color:#0000ff">question</span>(
      text      =&gt; <span style="color:#ffa500">"</span><span style="color:#ff0000">Would you like fries with that?</span><span style="color:#ffa500">"</span>,
      default   =&gt; 0,
   );
   <b>say</b> <span style="color:#ffa500">"</span><span style="color:#ff0000">Adding fries!</span><span style="color:#ffa500">"</span> <b>if</b> <span style="color:#0000ff">$answer</span>;</pre>

<p>The functional interface is just a friendly wrapper around Ask's object-oriented core.</p>

<h2><span>Boldly go</span></h2>

<p>Let's say that you want to hook up your script to your drive-through restaurant's voice recognition system. Ask's backends are all <a href="https://metacpan.org/module/Moo" class="podlinkpod">Moo</a> classes performing the <a href="https://metacpan.org/module/Ask::API" class="podlinkpod">Ask::API</a> role. It's really easy to write your own:</p>

<pre>   <b>package</b> <span style="color:#007f00">Ask::VoiceRecognition</span> {
      
      <b>use</b> <span style="color:#007f00">MyApp::Voice</span>::<span style="color:#007f00">Generator</span> ();
      <b>use</b> <span style="color:#007f00">MyApp::Voice</span>::<span style="color:#007f00">Recognition</span> ();
      
      <b>use</b> Moo;
      with <span style="color:#ffa500">'</span><span style="color:#ff0000">Ask::API</span><span style="color:#ffa500">'</span>;
      
      has generator =&gt; (
         is      =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">lazy</span><span style="color:#ffa500">'</span>,
         default =&gt; <b>sub </b>{ <span style="color:#007f00">MyApp::Voice</span>::<span style="color:#007f00">Generator</span>-&gt;new },
      );
      
      has recognition =&gt; (
         is      =&gt; <span style="color:#ffa500">'</span><span style="color:#ff0000">lazy</span><span style="color:#ffa500">'</span>,
         default =&gt; <b>sub </b>{ <span style="color:#007f00">MyApp::Voice</span>::<span style="color:#007f00">Recognition</span>-&gt;new },
      );
      
      <b>sub </b><span style="color:#007f00">info</span> {
         <b>my</b> <span style="color:#0000ff">$self</span> = <span style="color:#007f00">shift</span>;
         <b>my</b> <span style="color:#0000ff">%args</span> = <span style="color:#0000ff">@_</span>;
         <span style="color:#0000ff">$self</span>-&gt;<span style="color:#0000ff">generator</span>-&gt;<span style="color:#0000ff"><span>say</span></span>(<span style="color:#0000ff">$args</span>{text});
      }
      
      <b>sub </b><span style="color:#007f00">entry</span> {
         <b>my</b> <span style="color:#0000ff">$self</span> = <span style="color:#007f00">shift</span>;
         <b>my</b> <span style="color:#0000ff">%args</span> = <span style="color:#0000ff">@_</span>;
         <span style="color:#0000ff">$self</span>-&gt;<span style="color:#0000ff">info</span>(<span style="color:#0000ff">$args</span>{text}) <b>if</b> <span style="color:#007f00">exists</span> <span style="color:#0000ff">$args</span>{text};
         <b>return</b> <span style="color:#0000ff">$self</span>-&gt;<span style="color:#0000ff">recognition</span>-&gt;<span style="color:#0000ff">listen</span>(seconds =&gt; <span style="color:#00007f">30</span>);
      }
   }</pre>

<p>That's all there is to it!</p>

<p>The Ask::API provides default implementations of <code>question</code>, <code>file_selection</code>, <code>multiple_choice</code>, etc, which you can override if you choose to, but that is optional.</p>

<p>To force Ask to use your backend rather than the built-in ones, just set the <code>PERL_ASK_BACKEND</code> environment variable to the name of your module.</p>

<h2><span>Ask the future</span></h2>

<p>Ask is a young module and still needs some work. In particular:</p>

<ul>
<li>Detection of the best module for interacting with the user is naive. It can end up selecting, say, Gtk2 on a headless Linux box.</li>

<li>A native Windows GUI backend is planned. The Gtk2, Wx and Tk backends should all theoretically work on Windows, but rely on various library files being present.</li>
</ul>

<p>Ask is <a href="https://github.com/tobyink/p5-ask" class="podlinkpod">on GitHub</a> and <a href="https://bitbucket.org/tobyink/p5-ask" class="podlinkpod">on Bitbucket</a> so feel free to contribute improvements!</p>
]]>
    </content>
</entry>

<entry>
    <title>w00t! First CPAN upload of 2013!</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2013/01/w00t-first-cpan-upload-of-2013.html" />
    <id>tag:blogs.perl.org,2013:/users/toby_inkster//1019.4165</id>

    <published>2013-01-01T08:04:31Z</published>
    <updated>2013-01-01T00:11:15Z</updated>

    <summary>According to metacpan.org, MooX-ClassAttribute-0.001 was the first upload of 2013! Yay!...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>According to <a href="https://metacpan.org/recent">metacpan.org</a>, <a href="https://metacpan.org/release/TOBYINK/MooX-ClassAttribute-0.001">MooX-ClassAttribute-0.001</a> was the first upload of 2013! Yay!</p>]]>
        <![CDATA[<p>Yes, I did plan that. No, I didn't sit there and press the button. (<kbd>sleep</kbd> is a useful command-line tool.)</p>

<p>Meh... so now I notice I forgot to list the pre-requisites...</p>]]>
    </content>
</entry>

<entry>
    <title>cpantimes</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2012/12/cpantimes.html" />
    <id>tag:blogs.perl.org,2012:/users/toby_inkster//1019.4135</id>

    <published>2012-12-17T09:43:40Z</published>
    <updated>2012-12-17T10:05:24Z</updated>

    <summary>OK, so I decided to hack in support for submitting CPAN testers reports into cpanminus. I&apos;ve uploaded the result to CPAN in case anybody else wants to use it. After CPANPLUS and cpanminus, the logical name for it was cpantimes....</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="cpan-testers" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p><span class="caps">OK, </span>so I decided to hack in support for submitting <span class="caps">CPAN </span>testers reports into cpanminus. I've uploaded the result to <span class="caps">CPAN </span>in case anybody else wants to use it. After <span class="caps">CPANPLUS </span>and cpanminus, the logical name for it was <a href="https://metacpan.org/release/TOBYINK/App-cpantimes-1.501803">cpantimes</a>.</p>

<p>Here's how to use it...</p>]]>
        <![CDATA[
<ol>
<li>Install <a href="https://metacpan.org/release/TOBYINK/App-cpantimes-1.501803">cpantimes</a> using your current <span class="caps">CPAN </span>client. You will also want <a href="https://metacpan.org/module/Test::Reporter">Test::Reporter</a> and <a href="https://metacpan.org/module/Test::Reporter::Transport::Metabase">Test::Reporter::Transport::Metabase</a>.<br />
<samp>$ </samp><kbd>cpanm App::cpantimes Test::Reporter Test::Reporter::Transport::Metabase</kbd></li>
<li>Set up a Metabase profile. You will need this in order for your reports to be accepted by <span class="caps">CPAN </span>testers.<br />
<samp>$ </samp><kbd>metabase-profile</kbd><br />
<samp>...</samp><br />
<samp>$ </samp><kbd>mkdir $HOME/.cpantesters</kbd><br />
<samp>$ </samp><kbd>mv metabase_id.json $HOME/.cpantesters</kbd><br />
<samp>$ </samp><kbd>chmod 400 $HOME/.cpantesters/metabase_id.json</kbd></li>
<li>Now just use <kbd>cpant</kbd> whenever you'd normally use <kbd>cpanm</kbd>. Test reports will be silently submitted every time you install a distribution. You can even set up a shell alias so that when you type <kbd>cpanm</kbd> you get cpantimes.</li>
</ol>



<p>cpantimes is still at a very early stage of development. I literally started it yesterday evening. But have a play and let me know if you discover any bugs.</p>]]>
    </content>
</entry>

<entry>
    <title>Moo, how do you annoy me? Let me count the ways...</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2012/12/moo-how-do-you-annoy-me-let-me-count-the-ways.html" />
    <id>tag:blogs.perl.org,2012:/users/toby_inkster//1019.4106</id>

    <published>2012-12-06T17:11:18Z</published>
    <updated>2012-12-06T17:28:18Z</updated>

    <summary>OK, Moo is actually a rather nice little OO framework. It&apos;s inspired by Moose but not a clone of it. When Moo detects Moose has been loaded, it &quot;inflates&quot; all Moo classes and roles into Moose classes and roles, so...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p><span class="caps">OK, </span><a href="https://metacpan.org/release/Moo">Moo</a> is actually a rather nice little OO framework. It's inspired by <a href="https://metacpan.org/release/Moose">Moose</a> but not a clone of it.</p>

<p>When Moo detects Moose has been loaded, it "inflates" all Moo classes and roles into Moose classes and roles, so Moo code integrates with Moose code perfectly. Because of this, and Moo's very light memory and <span class="caps">CPU </span>footprint, many Moose-based projects are migrating to Moo. High profile migrations include <a href="https://metacpan.org/release/Throwable">Throwable</a>, <a href="https://metacpan.org/release/Message-Passing">Message-Passing</a> and <a href="https://metacpan.org/release/MooseX-Role-Loggable">MooseX-Role-Loggable</a>.</p>

<p>Not all Moose-based projects are easy to port to Moo. Some require a high level of introspection and meta-hackery that only Moose can provide. But if Moo does seem to be a good fit for your project, switching to Moo is not as simple as dropping the "<code>se</code>" from your "<code>use Moose</code>" lines. There are a number of incompatibilities between the declarative syntaxes of Moo and Moose.</p>

<p>I've recently released <a href="https://metacpan.org/release/MooX-late">MooX-late</a> to help smooth over the differences and translate Moose code to Moo. Currently it handles:</p>


<ul>
<li>stringy type constraints, like <code>isa =&gt; &quot;Str&quot;</code></li>
<li>non-reference defaults, like <code>default =&gt; 1</code></li>
<li>Moose's <code>lazy_build</code> shortcut</li>
<li>Exporting the <code>blessed</code> and <code>confess</code> functions like Moose does</li>
</ul>



<p>But I'd love to hear what other people think are the Moo annoyances. What is preventing you from porting simple classes and roles to Moo? What does Moose do for you that Moo does not? What features should I add to MooX-late?</p>]]>
        
    </content>
</entry>

<entry>
    <title>A Simple Plack/DBI Example</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2012/10/in-a-simple-mojoliciousdbi-example.html" />
    <id>tag:blogs.perl.org,2012:/users/toby_inkster//1019.3971</id>

    <published>2012-10-19T19:05:36Z</published>
    <updated>2012-10-19T19:28:11Z</updated>

    <summary>In A Simple Mojolicious/DBI Example Joel Berger demonstrates how to build a very simple CRUD web app (well, a CR one anyway) using Mojolicious and DBI. I was impressed at how concise it was, and wondered how my preferred technology...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="HTML" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="HTTP" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="PSGI" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Plack" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>In <a href="http://blogs.perl.org/users/joel_berger/2012/10/a-simple-mojoliciousdbi-example.html">A Simple Mojolicious/DBI Example</a> Joel Berger demonstrates how to build a very simple CRUD web app (well, a CR one anyway) using Mojolicious and DBI. I was impressed at how concise it was, and wondered how my preferred technology stack would compare.</p>

<p>I'm not a fan of template languages, preferring DOM manipulation. And rather than Mojo, I'm using Plack here. Anyway, this is what I came up with...</p>
]]>
        <![CDATA[<pre><code>#!/usr/bin/env plackup

use v5.14;
use DBI;
use HTML::HTML5::Parser;
use HTML::HTML5::Writer;
use Plack::Request;
use Plack::Response;

# connect to database
my $dbh = 'DBI'-&gt;connect("dbi:SQLite:database.db","","") or die "Could not connect";
my ($insert, $select);

while (1) {
   # create insert and select statements
   $insert = eval { $dbh-&gt;prepare('INSERT INTO people VALUES (?,?)') };
   $select = eval { $dbh-&gt;prepare('SELECT * FROM people') };
   # break out of loop if statements prepared
   last if $insert &amp;&amp; $select;

   # if statements didn't prepare, assume its because the table doesn't exist
   warn "Creating table 'people'\n";
   $dbh-&gt;do('CREATE TABLE people (name varchar(255), age int);');
}

my $template = 'HTML::HTML5::Parser'-&gt;load_html(IO =&gt; \*DATA);
my $writer   = 'HTML::HTML5::Writer'-&gt;new(markup =&gt; 'html', polyglot =&gt; 1);

# the PSGI app itself
my $app = sub {
   my $req = 'Plack::Request'-&gt;new(shift);
   my $res = 'Plack::Response'-&gt;new(200);

   if ($req-&gt;method eq 'POST') {
      $insert-&gt;execute(map $req-&gt;parameters-&gt;{$_}, qw( name age ));
      $res-&gt;redirect( $req-&gt;base );
   }   
   else {
      my $page  = $template-&gt;cloneNode(1);
      my $table = $page-&gt;getElementsByTagName('table')-&gt;get_node(1);
      $select-&gt;execute;
      while (my @row = $select-&gt;fetchrow_array) {
         my $tr = $table-&gt;addNewChild($table-&gt;namespaceURI, 'tr');
         $tr-&gt;appendTextChild(td =&gt; $_) for @row;
      }
      $res-&gt;body( $writer-&gt;document($page) );
   }

   $res-&gt;finalize;
};

__DATA__
&lt;!DOCTYPE html&gt;
&lt;title&gt;People&lt;/title&gt;
&lt;form action="insert" method="post"&gt;
   Name: &lt;input type="text" name="name"&gt; 
   Age: &lt;input type="text" name="age"&gt;
   &lt;input type="submit" value="Add"&gt;
&lt;/form&gt;
&lt;br&gt;
Data: &lt;br&gt;
&lt;table border="1"&gt;
   &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Age&lt;/th&gt;
   &lt;/tr&gt;
&lt;/table&gt;
</code></pre>
]]>
    </content>
</entry>

<entry>
    <title>Ooh, pretty!</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2012/09/ooh-pretty.html" />
    <id>tag:blogs.perl.org,2012:/users/toby_inkster//1019.3855</id>

    <published>2012-09-20T21:37:21Z</published>
    <updated>2012-09-20T21:38:26Z</updated>

    <summary>CPAN Ratings has had a face lift....</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p><a href="http://cpanratings.perl.org/">CPAN Ratings</a> has had a face lift.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Creating Your Own Perl</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/toby_inkster/2012/09/creating-your-own-perl.html" />
    <id>tag:blogs.perl.org,2012:/users/toby_inkster//1019.3807</id>

    <published>2012-09-09T17:54:30Z</published>
    <updated>2012-09-09T18:00:46Z</updated>

    <summary>Perl modules are not like dynamically loaded libraries in other programming languages. Thanks to the import function, sub prototypes, symbol table hacking, parser hooks, magic like Devel-Declare, ties and other voodoo, Perl modules can shape and craft the flavour of...</summary>
    <author>
        <name>Toby Inkster</name>
        <uri>http://tobyinkster.co.uk/</uri>
    </author>
    
        <category term="DSL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/toby_inkster/">
        <![CDATA[<p>Perl modules are not like dynamically loaded libraries in other programming languages. Thanks to the <code>import</code> function, sub prototypes, symbol table hacking, parser hooks, magic like <a href="https://metacpan.org/release/Devel-Declare">Devel-Declare</a>, ties and other voodoo, Perl modules can shape and craft the flavour of Perl that is available to their caller. A practical example: Perl's exception handling via <code>eval</code> and <code>$@</code> is weird, clunky and error-prone. But by loading <a href="https://metacpan.org/module/TryCatch">TryCatch</a> or <a href="https://metacpan.org/module/Try::Tiny">Try::Tiny</a> you get a clean syntax for catching exceptions that Just Works. You're not just loading a library and using it at arm's length; you're changing the very syntax of Perl - locally, within your module.</p>

<p>(Aside: there are of course plenty of modules that don't do any of this - say those that are designed to be used in an object-oriented fashion. Those are great too of course - different approaches are appropriate for solving different problems.)</p>

<p>Exception handling is not the only example. <a href="https://metacpan.org/module/List::Util">List::Util</a>, <a href="https://metacpan.org/module/Plack::Builder">Plack::Builder</a>, <a href="https://metacpan.org/module/Moose">Moose</a>, <a href="https://metacpan.org/module/MooseX::Method::Signatures">MooseX::Method::Signatures</a>, <a href="https://metacpan.org/module/syntax">syntax</a> (with its friends) and pretty much every module that uses <a href="https://metacpan.org/module/Exporter">Exporter</a> or similar all fall into this broad category of modules that shape the flavour of Perl being used.</p>

<p>When starting a new script, or a new module, this is what we do. We add a bunch of <code>use</code> statements to the top of the file to tweak Perl's flavour to our liking. We make Perl a more suitable language for getting the job done; we turn a general purpose programming language into a domain-specific language suitable for our exact task. This will often begin with something like <code>use 5.010; use strict; use warnings;</code>, but if you're writing anything non-trivial, it's likely that a bunch of other <code>use</code> statements will join them.</p>

<p>Which brings me to <b>Syntax::Collector</b>. The idea of Syntax::Collector is that in a large project which spans multiple Perl modules and scripts, there are certain flavour of Perl that we wish to apply across all files. That might be <code>use strict</code> and <code>use warnings</code> to ensure good practice is followed, and might also include <code>use Scalar::Util qw(blessed)</code> or <code>use List::Util qw(first reduce)</code> or <code>use Try::Tiny</code>. Syntax::Collector helps you capture that flavour in one module, and use that module in each script you write. Here's an example:</p>

<pre><code>package MyProject::Syntax;
our $VERSION = 1;
use Syntax::Collector -collect => '
use strict 0;
use warnings 0;
use true 0;
use feature 0 qw(say state switch);
no warnings 0 qw(void once uninitialized)
use Scalar::Util 1.23 qw(blessed);
use List::Util 0 qw(first reduce);
use Carp 0 qw(croak);
use Try::Tiny 0;
';</code></pre>

<p>(Aside: you might be horrified that Syntax::Collector's list of modules to import is a simple quoted string. Don't worry; we don't <code>eval</code> it. It's parsed and handled fairly sensibly. The purpose of using the Perl-like syntax within the string is to be friendly to people grepping through source code for <code>use Some::Module</code>.)</p>

<p>Then in each file of the project, we just <code>use MyProject::Syntax 1</code> and all the rest of that stuff is automatically imported. This not only has the advantage of reducing boiler-plate code, it can change the way you write Perl. Let's imagine that we're trying to find a parser that can handle HTML input:</p>

<pre><code>my ($htmlparser) = grep { $_->does_accept('text/html') } @parsers;</code></pre>

<p>That looks fine, and we might be happy with it, but if <code>@parsers</code> is a long list, then it's potentially pretty inefficient. After we've found the first HTML parser, we don't want to keep grepping through the list. The <code>first</code> function from List::Util would be much better:</p>

<pre><code>my $htmlparser = first { $_->does_accept('text/html') } @parsers;</code></pre>

<p>But if we're working on a module, and this is the only time we need <code>first</code> then we might sigh, ho hum, <code>grep</code> will do. We'll <code>die</code> when we really should <code>croak</code>. We'll check <code>defined ref</code> instead of <code>blessed</code>. But with Syntax::Collector, and all these functions loaded up-front, we're encouraged to use the right tool for the job.</p>

<p>Another advantage of Syntax::Collector is that it gives us a single place to declare all the project's dependencies. Later on, if we want to reduce dependencies, we have a single place to peruse the list. If you notice that the only part if List::MoreUtils that you're using is <code>uniq</code> then you can write your own <code>uniq</code> implementation (it's a one-liner) and use that instead. And you don't need to go through all your source files replacing references to List::MoreUtils, because the only reference is in your syntax module.</p>

<p><a href="https://metacpan.org/module/Syntax::Collector">Syntax::Collector 0.004</a> is on CPAN.</p>]]>
        
    </content>
</entry>

</feed>
