<?xml version="1.0" encoding="us-ascii"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Perl Advent Calendar 2011</title><id>http://perladvent.org/2011/</id><link href="http://perladvent.org/2011/atom.xml" rel="self"/><updated>2012-10-08T13:40:50-04:00</updated><author><name>Ricardo Signes</name></author><generator uri="http://search.cpan.org/dist/XML-Atom-SimpleFeed/" version="0.86">XML::Atom::SimpleFeed</generator><entry><title type="html">It&#38;#39;s Over!</title><link href="http://perladvent.org/2011/2011-12-25.html"/><id>http://perladvent.org/2011/2011-12-25.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Merry-Christmas-from-PerlAdvent.pm&#34;&gt;Merry Christmas from PerlAdvent.pm&lt;/h2&gt;

&lt;p&gt;Well, yesterday was the final day of our Advent calendar, and hopefully everyone enjoyed it! Now it&#38;#39;s Christmas and I&#38;#39;m off to enjoy some time with family, friends, and new toys.&lt;/p&gt;

&lt;p&gt;As always, the Perl Advent Calendar is a group effort, and I&#38;#39;d like to thank everyone who contributed this year: brian d foy, Cory G Watson, David Golden, David Wheeler, Jesse Luehrs, Piers Cawley, and Shawn M Moore. If you&#38;#39;d like to contribute an article for next year, you&#38;#39;ve got just about 365 days to do it! Lucky for you, 2012 is a leap year, and you&#38;#39;ll get an extra day for planning.&lt;/p&gt;

&lt;p&gt;If you want to help with the site or other things in the meantime, you can &lt;a href=&#34;http://mail.pm.org/mailman/listinfo/perladvent&#34;&gt;join our mailing list&lt;/a&gt; where we&#38;#39;ll be talking about work that needs to get done on things like the FAQ, the site generator, and all that sort of thing. You can find the &lt;a href=&#34;https://github.com/rjbs/Perl-Advent&#34;&gt;site&#38;#39;s contents on GitHub&lt;/a&gt;, which &lt;i&gt;should&lt;/i&gt; contain the 2011 articles by the time you see this. It&#38;#39;s not exactly how it should be, but it&#38;#39;s there.&lt;/p&gt;

&lt;p&gt;So until I&#38;#39;m back at Christmas 2012 &#38;ndash; if I don&#38;#39;t come to my senses and quit this job &#38;ndash; have a merry Christmas and an excellent new year!&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/rjbs/Perl-Advent&#34;&gt;https://github.com/rjbs/Perl-Advent&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://mail.pm.org/mailman/listinfo/perladvent&#34;&gt;http://mail.pm.org/mailman/listinfo/perladvent&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://www.perladvent.org/FAQ.html&#34;&gt;the soon-to-be-rewritten FAQ&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-25T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Where Does He Get Those Wonderful Codepoints?</title><link href="http://perladvent.org/2011/2011-12-24.html"/><id>http://perladvent.org/2011/2011-12-24.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;&#34;&gt;&#38;#x1D516;&#38;#x1D531;&#38;#x1D532;&#38;#x1D52D;&#38;#x1D526;&#38;#x1D521; &#38;#x1D518;&#38;#x1D52B;&#38;#x1D526;&#38;#x1D520;&#38;#x1D52C;&#38;#x1D521;&#38;#x1D522; &#38;#x1D517;&#38;#x1D52F;&#38;#x1D526;&#38;#x1D520;&#38;#x1D528;&#38;#x1D530;&lt;/h2&gt;

&lt;p&gt;I got interested in understanding how Unicode works for two reasons: I needed to understand it to do my job, and it gave me an improved ability to do &lt;a href=&#34;https://twitter.com/rjbs/status/149640554597199872&#34;&gt;stupid things on Twitter&lt;/a&gt;. Mostly, today I want to talk about the latter.&lt;/p&gt;

&lt;p&gt;So, for example, how did I make that stupid section header above? (By the way, if you can&#38;#39;t read it, you should probably go install a more complete Unicode font, like Symbola!) Well, I knew that Unicode 6 had introduced Fraktur characters, and if I knew how they were named, I could start from there, so I used the &lt;code&gt;uni&lt;/code&gt; command provided with &lt;a href=&#34;https://metacpan.org/module/App::Uni&#34;&gt;App::Uni&lt;/a&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ uni fraktur&lt;br /&gt;1D504 &#38;#x1D504; MATHEMATICAL FRAKTUR CAPITAL A&lt;br /&gt;1D505 &#38;#x1D505; MATHEMATICAL FRAKTUR CAPITAL B&lt;br /&gt;1D507 &#38;#x1D507; MATHEMATICAL FRAKTUR CAPITAL D&lt;br /&gt;1D508 &#38;#x1D508; MATHEMATICAL FRAKTUR CAPITAL E&lt;br /&gt;1D509 &#38;#x1D509; MATHEMATICAL FRAKTUR CAPITAL F&lt;br /&gt;1D50A &#38;#x1D50A; MATHEMATICAL FRAKTUR CAPITAL G&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This a stupidly useful tool for being a goofball. Did you know that I mostly use my programming skills to make dumb jokes on the internet? Yeah, this is your surprised face: &#38;#x1F610;&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ uni neutral&lt;br /&gt;A64E &#38;#xA64E; CYRILLIC CAPITAL LETTER NEUTRAL YER&lt;br /&gt;A64F &#38;#xA64F; CYRILLIC SMALL LETTER NEUTRAL YER&lt;br /&gt;1F610 &#38;#x1F610; NEUTRAL FACE&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;The-Level&#34;&gt;The &#38;#x1D441;&#38;#x1D452;&#38;#x1D465;&#38;#x1D461; Level&lt;/h2&gt;

&lt;p&gt;So, &lt;code&gt;uni&lt;/code&gt; is great for finding characters quickly by name. Sometimes, though, you want to find characters based on other criteria. For example, when I see somebody trying to use &lt;code&gt;m{\d}&lt;/code&gt; to match ASCII digits, I want to give them an example of some of the things that they really don&#38;#39;t think should be matched. Tom Christiansen is one of Perl&#38;#39;s chief Unicode gurus, and he&#38;#39;s written a bunch of weird and useful tools. brian d foy packaged those up and now it&#38;#39;s easy for anybody to install them. One of the tools is &lt;code&gt;unichars&lt;/code&gt;, which lets you find characters based on many more criteria than their names. For example, to enlighten the guy using &lt;code&gt;m{\d}&lt;/code&gt;, I want to find digits that aren&#38;#39;t in &lt;code&gt;[0-9]&lt;/code&gt; and I&#38;#39;m going to pick the seven from each script, because seven is a funny number:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ unichars &#38;#39;\d&#38;#39; &#38;#39;$_ !~ /[0-9]/&#38;#39; &#38;#39;NAME =~ /SEVEN/&#38;#39;&lt;br /&gt;...&lt;br /&gt;&#38;#x96D;  U+096D DEVANAGARI DIGIT SEVEN&lt;br /&gt;&#38;#x9ED;  U+09ED BENGALI DIGIT SEVEN&lt;br /&gt;&#38;#xA6D;  U+0A6D GURMUKHI DIGIT SEVEN&lt;br /&gt;&#38;#xAED;  U+0AED GUJARATI DIGIT SEVEN&lt;br /&gt;&#38;#xB6D;  U+0B6D ORIYA DIGIT SEVEN&lt;br /&gt;&#38;#xBED;  U+0BED TAMIL DIGIT SEVEN&lt;br /&gt;&#38;#xC6D;  U+0C6D TELUGU DIGIT SEVEN&lt;br /&gt;&#38;#xCED;  U+0CED KANNADA DIGIT SEVEN&lt;br /&gt;&#38;#xD6D;  U+0D6D MALAYALAM DIGIT SEVEN&lt;br /&gt;&#38;#xE57;  U+0E57 THAI DIGIT SEVEN&lt;br /&gt;&#38;#xED7;  U+0ED7 LAO DIGIT SEVEN&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;I just specified my three criteria as arguments to the command:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;a digit: &lt;code&gt;\d&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;not in [0-9]: &lt;code&gt;$_ !~ /[0-9]/&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;seven: &lt;code&gt;NAME =~ /SEVEN/&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could also replace that second rule with, say, &lt;code&gt;&#38;#39;\P{ASCII}&#38;#39;&lt;/code&gt;. There&#38;#39;s more than one way to do it. There are some important things to know, though. By default, for example, &lt;code&gt;unichars&lt;/code&gt; won&#38;#39;t search the supplementary multilingual plane or the so-called &#38;quot;astral&#38;quot; plane. That means that this vital search will fail:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ unichars &#38;#39;NAME =~ /WEARY/&#38;#39;&lt;br /&gt;(nothing)&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;You meant:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ unichars -a &#38;#39;NAME =~ /WEARY/&#38;#39;&lt;br /&gt;&#38;#x1F629;  U+1F629 WEARY FACE&lt;br /&gt;&#38;#x1F640;  U+1F640 WEARY CAT FACE&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Also, the sophistication of &lt;code&gt;unichars&lt;/code&gt; comes at a price: speed. Searching for that weary cat face with &lt;code&gt;uni&lt;/code&gt; takes about 0.144s on my laptop. Searching with &lt;code&gt;unichars&lt;/code&gt;, 14.899.&lt;/p&gt;

&lt;p&gt;When you&#38;#39;re just trying to make a stupid joke on Twitter, those 14 seconds aren&#38;#39;t worth spending. On the other hand, when you need to actually search for characters matching certain criteria, &lt;code&gt;unichars&lt;/code&gt; can do it, and &lt;code&gt;uni&lt;/code&gt; can&#38;#39;t.&lt;/p&gt;

&lt;h2 id=&#34;Two-More-Tools&#34;&gt;Two More Tools&lt;/h2&gt;

&lt;p&gt;Unicode::Tussle comes with a bunch more tools, but I&#38;#39;ll just show you two more, briefly. &lt;code&gt;uninames&lt;/code&gt; is a bit more like &lt;code&gt;uni&lt;/code&gt; in that its primary job is to search character descriptions, but its searches aren&#38;#39;t limited to character &lt;i&gt;names&lt;/i&gt;. It looks at the whole description. For example:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ uninames face&lt;br /&gt;&#38;nbsp;&#38;#x222F;  222F  SURFACE INTEGRAL&lt;br /&gt;&#38;nbsp;&#38;nbsp;# 222E 222E&lt;br /&gt;&#38;nbsp;&#38;#x2313;  2313  SEGMENT&lt;br /&gt;&#38;nbsp;&#38;nbsp;= position of a surface&lt;br /&gt;&#38;nbsp;&#38;#x231A;  231A  WATCH&lt;br /&gt;&#38;nbsp;&#38;nbsp;x (alarm clock - 23F0)&lt;br /&gt;&#38;nbsp;&#38;nbsp;x (clock face one oclock - 1F550)&lt;br /&gt;&#38;nbsp;&#38;#x23F0;  23F0 ALARM CLOCK&lt;br /&gt;&#38;nbsp;&#38;nbsp;x (watch - 231A)&lt;br /&gt;&#38;nbsp;&#38;nbsp;x (clock face one oclock - 1F550)&lt;br /&gt;...&lt;br /&gt;&#38;nbsp;&#38;#x263A;  263A  WHITE SMILING FACE&lt;br /&gt;&#38;nbsp;&#38;nbsp;= have a nice day!&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;We get &lt;code&gt;SURFACE INTEGRAL&lt;/code&gt; because it matches &lt;code&gt;/face/i&lt;/code&gt;, but why do we get &lt;code&gt;SEGMENT&lt;/code&gt; or &lt;code&gt;WATCH&lt;/code&gt;? It&#38;#39;s because they&#38;#39;re related to character with &#38;quot;face&#38;quot; in their descriptions. Sometimes, you&#38;#39;ll get a match against a comment about the characters&#38;#39; usage:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ uninames fraktur&lt;br /&gt;&#38;nbsp;&#38;#x17F;  017F  LATIN SMALL LETTER LONG S&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;* in common use in Roman types until the 18th century&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;* in current use in Fraktur and Gaelic types&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Finally, there&#38;#39;s &lt;code&gt;uniprops&lt;/code&gt;. This is a &lt;i&gt;wonderfully&lt;/i&gt; useful tool, in &lt;i&gt;very limited circumstances&lt;/i&gt;. Most often, for me, it comes up when I&#38;#39;ve got some weird input. Say some user&#38;#39;s name isn&#38;#39;t working with some data validator. The guy who wrote that validator required names to be (for some insane reason) Latin letters that were either uppercase or lowercase. Our other input validator only has the first half of that constraint: Latin letters. What&#38;#39;s happening? Well, the user causing us problems is going by the name &#38;ldquo;&#38;#x1D3F;&#38;#x1D36;&#38;#x1D2E;&#38;#x2E2;&#38;rdquo; &#38;ndash; what can &lt;code&gt;uniprops&lt;/code&gt; tell us about those?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ uniprops &#38;lt;1d3f&#38;gt;&lt;br /&gt;U+1D3F &#38;lsaquo;&#38;#x1D3F;&#38;rsaquo; \N{MODIFIER LETTER CAPITAL R}&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;\w \pL \p{L_} \p{Lm}&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;All Any Alnum Alpha Alphabetic Assigned InPhoneticExtensions Case_Ignorable&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;CI Cased Changes_When_NFKC_Casefolded CWKCF Dia Diacritic L Lm Gr_Base&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Grapheme_Base Graph GrBase ID_Continue IDC ID_Start IDS Letter L_ Latin&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Latn Modifier_Letter Lower Lowercase Phonetic_Extensions Print Word&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;XID_Continue XIDC XID_Start XIDS X_POSIX_Alnum X_POSIX_Alpha&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;X_POSIX_Graph X_POSIX_Lower X_POSIX_Print X_POSIX_Word&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;So, it&#38;#39;s Latin, a Letter, and Lowercase, but not a Lowercase_Letter. What?? Surely this is an anomaly..? We can find out with &lt;code&gt;unichars&lt;/code&gt;!&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ unichars &#38;#39;\p{Letter}&#38;#39; &#38;#39;\P{Lowercase_Letter}&#38;#39; &#38;#39;\P{Uppercase_Letter}&#38;#39; &#38;#39;\p{Latin}&#38;#39;&lt;br /&gt;(131 characters listed)&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;What&#38;#39;s the lesson here? You and the other guy should learn what those categories &lt;i&gt;mean&lt;/i&gt;. Once you&#38;#39;ve started doing that, you&#38;#39;ll be well on your way down the rabbit hole, and you&#38;#39;ll start to find all new uses for these tools&#38;hellip; but none is likely to be as much fun as making stupid Tweets.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Unicode::Tussle&#34;&gt;Unicode::Tussle&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::Uni&#34;&gt;App::Uni&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-24T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title type="html">It Boiled Plate So You Don&#38;#39;t Have To!</title><link href="http://perladvent.org/2011/2011-12-23.html"/><id>http://perladvent.org/2011/2011-12-23.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;ref-reftype-overload-and-isa&#34;&gt;ref, reftype, overload, and isa&lt;/h2&gt;

&lt;p&gt;&#38;quot;The &lt;code&gt;process_foos&lt;/code&gt; method accepts either something that does the Foo role, an arrayref of such things, or a callback that should return one of the previous options.&#38;quot;&lt;/p&gt;

&lt;p&gt;This kind of behavior is pretty common in Perl. It&#38;#39;s pretty convenient, too! The problem is that it is &lt;i&gt;incredibly&lt;/i&gt; ambiguous because Perl can behave in so many ways. We might write an implementation like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;process_foos&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_one_foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;DOES&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Foo&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_foo_arr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ref&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ARRAY&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;process_foos&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ref&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;CODE&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;How many problems are there here, though? Well&#38;hellip;&lt;/p&gt;

&lt;p&gt;First off, that &lt;code&gt;-&#38;gt;DOES&lt;/code&gt; call is no good. It will blow up if we pass in an arrayref, because you can&#38;#39;t call &lt;code&gt;DOES&lt;/code&gt; or &lt;code&gt;isa&lt;/code&gt; (or any other method) on an unblessed reference. So, the &lt;i&gt;incredibly unfortunate&lt;/i&gt; way people dealt with this in the past was:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_one_foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;UNIVERSAL::isa&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Foo&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Notice how I devolved back from &lt;code&gt;DOES&lt;/code&gt; to &lt;code&gt;isa&lt;/code&gt;? That&#38;#39;s because &lt;code&gt;UNIVERSAL::DOES&lt;/code&gt; detects and objects to this kind of abuse &#38;ndash; but it doesn&#38;#39;t give you a safe way to check it in one step, so now the new &lt;i&gt;incredibly unfortunate&lt;/i&gt; way people deal with this is:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_one_foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;blessed&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;DOES&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Foo&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This is fine, if you really wanted a Foo &lt;i&gt;object&lt;/i&gt;, but sometimes a &lt;i&gt;class&lt;/i&gt; is just as good, if it has the right interface. The whole thing about classes and instances sharing the same set of methods is kind of its own problem&#38;hellip; so let&#38;#39;s just say &#38;quot;this is a mess&#38;quot; and keep going.&lt;/p&gt;

&lt;p&gt;So, this one seems less &lt;i&gt;obviously&lt;/i&gt; bad:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_foo_arr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ref&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ARRAY&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;&#38;hellip;but it&#38;#39;s still not perfect. For one thing, some chucklehead might have blessed his object into &lt;code&gt;ARRAY&lt;/code&gt;. Frankly, I think that if you&#38;#39;ve got that going on in your code base, you probably deserve what you get, but you can protect against it, any many do, with:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_foo_arr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;reftype&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ARRAY&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Now we&#38;#39;re really checking the underlying reference type, not just the return of &lt;code&gt;ref&lt;/code&gt;, which has &lt;i&gt;two&lt;/i&gt; jobs. That&#38;#39;s better, except &lt;i&gt;not really&lt;/i&gt;. See, &lt;code&gt;reftype&lt;/code&gt; is bypassing &lt;code&gt;ref&lt;/code&gt; &#38;ndash; which seemed like a good thing when &lt;code&gt;ref&lt;/code&gt; sometimes returned &lt;code&gt;ARRAY&lt;/code&gt; but now it means we don&#38;#39;t know whether the thing was blessed! So you have a couple options. One is:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_foo_arr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;blessed&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;reftype&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ARRAY&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Okay, that&#38;#39;s not too, too bad. Let&#38;#39;s stick with it for now.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;process_foos&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ref&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;CODE&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Yup, this one has the same problem as the above. So, maybe you want to use the same solution!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  return $self-&#38;gt;process_foos( $arg-&#38;gt;() )
    if ! blessed $arg and reftype $arg eq &#38;#39;CODE&#38;#39;;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, the astute abuse-o-philes will remember, here, &#38;quot;Wait! What if you provided an &lt;i&gt;object&lt;/i&gt; that is &lt;i&gt;overloaded for &lt;code&gt;&#38;amp;{}&lt;/code&gt;&lt;/i&gt;!?&#38;quot; And you know what? I&#38;#39;m going to take a step back and just say what I think: &lt;i&gt;that isn&#38;#39;t even abuse!&lt;/i&gt; Closures and objects are closely related concepts, and the idea that your object can behave like a closure &#38;ndash; at least by providing a subref-like calling interface &#38;ndash; is totally reasonable. I have done it, I enjoyed it, and I would do it again!&lt;/p&gt;

&lt;p&gt;So, what did you really need to test for?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;reftype&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;CODE&#39;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;operator&#34;&gt;||&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;blessed&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;overload::Method&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;&#38;amp;{}&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Yes. &lt;i&gt;Of course&lt;/i&gt; I think it&#38;#39;s ridiculous, too. Even better, you have to do it for the &lt;code&gt;ARRAY&lt;/code&gt; bit above, because somebody might have overloaded &lt;code&gt;@{}&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;Help-&#34;&gt;Help!!&lt;/h2&gt;

&lt;p&gt;Don&#38;#39;t worry! There&#38;#39;s help!&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Params::Util&#34;&gt;Params::Util&lt;/a&gt; provides a treatment for this madness.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Params::Util&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;:ALL&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;process_foos&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_one_foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_CLASSISA&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Foo&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_INSTANCE&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Foo&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;_process_foo_arr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_ARRAYLIKE&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;process_foos&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_CODELIKE&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;(Note that I had to use &lt;code&gt;_CLASSISA&lt;/code&gt;, which as the name implies uses &lt;code&gt;-&#38;gt;isa&lt;/code&gt; &#38;ndash; Params::Util does not &lt;i&gt;yet&lt;/i&gt; have &lt;code&gt;_CLASSDOES&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;These funky, hard-to-miss functions encapsulate all these kinds of checks, but they do them &lt;i&gt;the right way&lt;/i&gt;. There&#38;#39;s &lt;code&gt;_SCALAR&lt;/code&gt; to check for a plain, defined, unblessed scalar of nonzero length &#38;ndash; and if you want a plain, defined, unblessed scalar length and have no problem with zero length, there&#38;#39;s &lt;code&gt;_SCALAR0&lt;/code&gt;. There are routines for hashrefs, non-empty hashrefs, or things that can act like hashrefs if you want. There are tests for numberness, positive integerhood, and non-negative integerhood. If you look at list of its routines, you can probably guess what almost all of them do, and you can start using them immediately, replacing the code you have that&#38;#39;s just waiting to get tickled by some stupid edge case.&lt;/p&gt;

&lt;p&gt;Here&#38;#39;s that list:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;_STRING     _IDENTIFIER&lt;br /&gt;_CLASS      _CLASSISA   _SUBCLASS  _DRIVER&lt;br /&gt;_NUMBER     _POSINT     _NONNEGINT&lt;br /&gt;_SCALAR     _SCALAR0&lt;br /&gt;_ARRAY      _ARRAY0     _ARRAYLIKE&lt;br /&gt;_HASH       _HASH0      _HASHLIKE&lt;br /&gt;_CODE       _CODELIKE&lt;br /&gt;_INVOCANT   _REGEX      _INSTANCE&lt;br /&gt;_SET        _SET0&lt;br /&gt;_HANDLE&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;My only parting advice? Avoid &lt;code&gt;_STRING&lt;/code&gt;. It accepts globs!&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Params::Util&#34;&gt;Params::Util&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-23T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Less Tedium, More Transactions</title><link href="http://perladvent.org/2011/2011-12-22.html"/><id>http://perladvent.org/2011/2011-12-22.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;A frequent pattern when writing database-backed applications with the &lt;a href=&#34;https://metacpan.org/module/DBI&#34;&gt;DBI&lt;/a&gt; is to connect to the database and cache the database handle somewhere. A simplified example:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyApp::DB&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBI&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$DBH&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBI&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;DBI:SQLite:dbname=myapp.db&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;PrintError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;RaiseError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;AutoCommit&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;sqlite_unicode&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$DBH&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Just load MyApp::DB anywhere in your app and, whenever you want to use the database, grab the handle from &lt;code&gt;MyApp::DB-&#38;gt;dbh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This pattern is common enough that &lt;a href=&#34;https://metacpan.org/module/Apache::DBI&#34;&gt;Apache::DBI&lt;/a&gt; was created to magically do it for you on mod_perl, and the DBI added &lt;a href=&#34;https://metacpan.org/module/DBI#connect_cached&#34;&gt;&lt;code&gt;connect_cached()&lt;/code&gt;&lt;/a&gt; so that it could cache connections itself. However, each of these solutions has some issues:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;What happens when your program forks? Apache::DBI handles this condition, but neither the home-grown solution nor &lt;code&gt;connect_cached()&lt;/code&gt; does, and identifying a forked database handle as the source of a crash is notoriously unintuitive.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What happens when your program spawns a new thread? Sure, some DBI drivers might still work, but others might not. Best to treat new threads the same as new processes and reconnect to the database. Neither Apache::DBI nor &lt;code&gt;connect_cached()&lt;/code&gt; deal with threading issues, and of course neither does the custom solution.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache::DBI is magical and mysterious; but the magic comes with serious side-effects. Apache::DBI plugs itself right into the DBI itself, replacing its connection methods (which is why load ordering is so important to use it properly). Knowledge of Apache::DBI is actually built right into the DBI itself, meaning that the magic runs deep and both ways. These are pretty serious violations of encapsulation in both directions.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;connect_cached()&lt;/code&gt; has a bit of its own unfortunate magic. Every call to &lt;code&gt;connect_cached()&lt;/code&gt; resets the connection attributes. So if you have code in one place that starts a transaction, and code elsewhere but executed in the same scope that also fetches a &lt;code&gt;connect_cached()&lt;/code&gt; handle, the transaction will be committed then and there, even though the code that started it might not be done with it. One can &lt;a href=&#34;http://justatheory.com/computers/programming/perl/dbi-connect-cached-hack.html&#34;&gt;work around this issue via callbacks&lt;/a&gt;, but it&#38;#39;s a bit of a hack.&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a custom caching solution avoids the magic, but getting fork- and thread-safety right is surprisingly non-trivial, in the same way that &lt;a href=&#34;http://perladvent.org/2011/2011-12-17.html&#34;&gt;doing your own exception-handling is surprisingly non-trivial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector&#34;&gt;DBIx::Connector&lt;/a&gt;, a module that efficiently manages your database connections in a thread- and fork-safe manner so that you don&#38;#39;t have to. If you already have a custom solution, switching to DBIx::Connector is easy. Here&#38;#39;s a revision of MyApp::DB that uses it:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyApp::DB&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBIx::Connector&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBIx::Connector&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;DBI:SQLite:dbname=myapp.db&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;PrintError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;RaiseError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;AutoCommit&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;sqlite_unicode&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Simple, right? You pass exactly the same parameters to &lt;code&gt;DBIx::Connector-&#38;gt;new&lt;/code&gt; that you passed to &lt;code&gt;DBI-&#38;gt;connect&lt;/code&gt;. The DBIx::Connector object simply proxies the DBI. You want the database handle itself, just call &lt;code&gt;dbh()&lt;/code&gt; and proceed as usual, confident that if your app forks or spawns new threads, your database handle will be safe. Why? Because DBIx::Connector detects such changes, and re-connects to the database, being sure to properly dispose of the original connection. But really, you don&#38;#39;t have to worry about that, because DBIx::Connector does the worrying for you.&lt;/p&gt;

&lt;h4 id=&#34;Execution-Methods&#34;&gt;Execution Methods&lt;/h4&gt;

&lt;p&gt;DBIx::Connector is very good at eliminating the &lt;a href=&#34;http://www.modernperlbooks.com/mt/2011/11/on-technical-friction.html&#34;&gt;technical friction&lt;/a&gt; of process and thread management. But that&#38;#39;s not all there is to it.&lt;/p&gt;

&lt;p&gt;Although you can just fetch the DBI handle from your DBIx::Connector object and go, a better approach is to use its execution methods. These methods scope execution to a code block. Here&#38;#39;s an example using &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector#run&#34;&gt;&lt;code&gt;run()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;That may not seem so useful, and is more to type, but the real power comes from the &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector#txn&#34;&gt;&lt;code&gt;txn()&lt;/code&gt;&lt;/a&gt; method. &lt;code&gt;txn()&lt;/code&gt; executes the code block within the scope of a transaction. So where you normally would write something like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Try::Tiny&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;  &lt;br /&gt;&lt;span class=&#34;word&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;begin_work&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;    # do stuff...&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;commit&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;rollback&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The &lt;code&gt;try()&lt;/code&gt; method scopes the transaction for you, so that you can just focus on the work to be done and transaction management:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Try::Tiny&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;        # do stuff...&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;There&#38;#39;s no need to call &lt;code&gt;begin_work&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, or &lt;code&gt;rollback&lt;/code&gt;, as &lt;code&gt;txn()&lt;/code&gt; does all that for you. Furthermore, it improves the maintainability of your code, as the scope of the transaction is much more clearly defined as the scope of the code block. Additional calls to &lt;code&gt;txn()&lt;/code&gt; or &lt;code&gt;run()&lt;/code&gt; within that block are harmless, and just become part of the same transaction:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@queries&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$expensive_query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$another_expensive_query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Even cooler is the &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector#svp&#34;&gt;&lt;code&gt;svp()&lt;/code&gt;&lt;/a&gt; method, which scopes execution of a code block to a savepoint, or subtransaction, if your database supports it (all of the drivers currently supported by DBIx::Connector do). For example, this transaction will commit the insertion of values 1 and 3, but not 2:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;word&#34;&gt;MyApp::DBH&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO table1 VALUES (1)&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;svp&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO table1 VALUES (2)&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;OMGWTF?&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;warn&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Savepoint failed: $_\n&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO table1 VALUES (3)&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h4 id=&#34;Connection-Management&#34;&gt;Connection Management&lt;/h4&gt;

&lt;p&gt;The recommended pattern for using a cached DBI handle is to call &lt;a href=&#34;https://metacpan.org/module/DBI#ping&#34;&gt;&lt;code&gt;ping()&lt;/code&gt;&lt;/a&gt; when you fetch it from the cache, and reconnect if it returns false. Apache::DBI and &lt;code&gt;connect_cached()&lt;/code&gt; do this for you, and so does DBIx::Connector. However, in a busy application &lt;code&gt;ping()&lt;/code&gt; can get called &lt;i&gt;a lot&lt;/i&gt;. &lt;a href=&#34;http://pgexperts.com/&#34;&gt;We&lt;/a&gt; recently did some query analysis for a client, and found that 1% of the database execution time was taken up with &lt;code&gt;ping()&lt;/code&gt; calls. That may not sound like a lot, but looking at the numbers, it amounted to 100K pings &lt;i&gt;per hour&lt;/i&gt;. For something that just returns true 99.9*% of the time, it seems a bit silly.&lt;/p&gt;

&lt;p&gt;Enter DBIx::Connector &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector#Connection-Modes&#34;&gt;connection modes&lt;/a&gt;. The default mode is &#38;quot;ping&#38;quot;, as that&#38;#39;s what most installations are accustomed to. A second mode is &#38;quot;no_ping&#38;quot;, which simply disables pings. I don&#38;#39;t recommend that.&lt;/p&gt;

&lt;p&gt;A better solution is to use &#38;quot;fixup&#38;quot; mode. This mode doesn&#38;#39;t normally call &lt;code&gt;ping()&lt;/code&gt; either. However, if a code block passed to &lt;code&gt;run()&lt;/code&gt; or &lt;code&gt;txn()&lt;/code&gt; throws an exception, &lt;i&gt;then&lt;/i&gt; DBIx::Connector will call &lt;code&gt;ping()&lt;/code&gt;. If it returns false, DBIx::Connector reconnects to the database and executes the code block again. This configuration should handle some common situations, such as idle timeouts, without bothering you about it.&lt;/p&gt;

&lt;p&gt;Specify &#38;quot;fixup&#38;quot; mode whenever you call an execution method, like so:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;fixup&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;You can also specify that your connection always use &#38;quot;fixup&#38;quot; via the &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector#fixup&#34;&gt;&lt;code&gt;fixup()&lt;/code&gt;&lt;/a&gt; accessor. Modify the caching library like so (line 8 is new):&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBIx::Connector&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;DBI:SQLite:dbname=myapp.db&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;PrintError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;RaiseError&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;AutoCommit&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;sqlite_unicode&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;fixup&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# &#11013; &#11013; &#11013;  enter fixup mode!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$CONN&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;However, you must be more careful with fixup mode than with ping mode, because a code block can be executed twice. So you must be sure to write it such that there are no side effects to multiple executions. Don&#38;#39;t do this, for example:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;fixup&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO foo (count) VALUES(?)&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# may be 1 or 2&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Will it insert a value of &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;2&lt;/code&gt;? It&#38;#39;s much safer to remove non-transactional code from the block, like so:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;operator&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;fixup&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO foo (count) VALUES(?)&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# can only be 1&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;An even trickier pattern to watch out for is something like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$user&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;rjbs&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$conn&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;fixup&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO users (nick) VALUES (?)&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$user&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;    # Do some other stuff...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;INSERT INTO log (msg) VALUES (?)&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Created user&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If the database disconnects between the first and second calls to &lt;code&gt;do&lt;/code&gt;, and DBIx::Connector manages to re-connect and run the block again, you might get a unique key violation on the first call to &lt;code&gt;do&lt;/code&gt;. This is because we&#38;#39;ve used the &lt;code&gt;run()&lt;/code&gt; method. In the fist execution of the block, user &#38;quot;rjbs&#38;quot; was inserted and autocommitted. On the second call, user &#38;quot;rjbs&#38;quot; is already there, and because it&#38;#39;s a username, we get a unique key violation.&lt;/p&gt;

&lt;p&gt;The rule of thumb here is to use &lt;code&gt;run()&lt;/code&gt; only for database reads, and to use &lt;code&gt;txn()&lt;/code&gt; (and &lt;code&gt;svp()&lt;/code&gt;) for writes. &lt;code&gt;txn()&lt;/code&gt; will ensure that the transaction is rolled back, so the second execution of the code block will be side-effect-free.&lt;/p&gt;

&lt;h4 id=&#34;Pedigree&#34;&gt;Pedigree&lt;/h4&gt;

&lt;p&gt;DBIx::Connector is derived from patterns originally implemented for &lt;a href=&#34;https://metacpan.org/module/DBIx::Class&#34;&gt;DBIx::Class&lt;/a&gt;, though it&#38;#39;s nearly all original code. The upside for those of us who don&#38;#39;t use ORMs is that we get this independent piece of ORM-like behavior without its ORMishness. So if you&#38;#39;re a database geek like me, DBIx::Connector is a great way to reduce &lt;a href=&#34;http://www.modernperlbooks.com/mt/2011/11/on-technical-friction.html&#34;&gt;technical friction&lt;/a&gt; without buying into the whole idea of an ORM.&lt;/p&gt;

&lt;p&gt;As it turns out, &lt;a href=&#34;https://metacpan.org/module/DBIx::Connector&#34;&gt;DBIx::Connector&lt;/a&gt; is good not just for straight-to-database users, but also for ORMs. Both &lt;a href=&#34;https://metacpan.org/module/DBIx::Class&#34;&gt;DBIx::Class&lt;/a&gt; and &lt;a href=&#34;https://metacpan.org/module/Rose::DB&#34;&gt;Rose::DB&lt;/a&gt; have plans to replace their own caching and transaction-handling implementations with DBIx::Connector under the hood. That will be great for everyone, as the problems will all be solved in this one place.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/DBIx::Connector&#34;&gt;DBIx::Connector&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/DBI&#34;&gt;DBI&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/DBIx::Class&#34;&gt;DBIx::Class&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Rose::DB&#34;&gt;Rose::DB&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-22T00:00:00-05:00</updated><category term="Perl"/><author><name>David Wheeler</name></author></entry><entry><title>A Shortcut to Unicode</title><link href="http://perladvent.org/2011/2011-12-21.html"/><id>http://perladvent.org/2011/2011-12-21.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Unicode is notoriously difficult for programmers to use correctly. Wouldn&#38;#39;t it be swell if there were a module you could use to make your program fully Unicode-aware and -correct?&lt;/p&gt;

&lt;p&gt;Unfortunately such a thing could never exist, because Unicode is so much more than just English-plus-lots-of-funny-characters. It&#38;#39;s a system for handling the writing systems of the thousands of languages in the world. Daunting? You betcha.&lt;/p&gt;

&lt;p&gt;There is just too much ambiguity in Perl&#38;#39;s builtin functions to transparently upgrade them to be correct in the face of Unicode.&lt;/p&gt;

&lt;h3 id=&#34;utf8::all&#34;&gt;&lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Before you lose all hope, know that there &lt;i&gt;is&lt;/i&gt; a module, &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt;, that can get you most of the way to Unicode nirvana. It was borne out of the &lt;a href=&#34;https://metacpan.org/module/perl5i&#34;&gt;perl5i&lt;/a&gt; project, quickly spun out as a useful standalone module.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; sets up the most common channels that your program will use to interact with the outside world to manage the UTF-8 encoding and decoding for you. That means that when you, say, shift off an argument from &lt;code&gt;@ARGV&lt;/code&gt;, you will get a &lt;i&gt;character string&lt;/i&gt; instead of &lt;i&gt;octets&lt;/i&gt;. When you log to &lt;code&gt;STDERR&lt;/code&gt;, &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; ensures that the &lt;i&gt;characters&lt;/i&gt; you &lt;code&gt;warn&lt;/code&gt; are encoded to the &lt;i&gt;octets&lt;/i&gt; that the outside world expects.&lt;/p&gt;

&lt;p&gt;While a full explanation of the difference between characters and octets is beyond the scope of this article, it is important to know that any time you are dealing with &lt;b&gt;text&lt;/b&gt; you need to operate on &lt;b&gt;characters&lt;/b&gt;. Violate this rule and you&#38;#39;re likely to end up with garbage.&lt;/p&gt;

&lt;p&gt;Say we have a program that greets the name you pass in.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;version&#34;&gt;5.14.2&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;warnings&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;join&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot; &#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@ARGV&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;HI &#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;uc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;!&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Run this with &#38;quot;Santa Claus&#38;quot; and you get &#38;quot;HI SANTA CLAUS!&#38;quot;. Great! But once you leave the 26-letter English things get worse quickly. Try the French &#38;quot;P&#38;egrave;re No&#38;euml;l&#38;quot; and you&#38;#39;ll get &#38;quot;HI P&#38;egrave;RE NO&#38;euml;L!&#38;quot; Not perfect, but at least it stays readable. Go further afield to the Japanese &#38;quot;&#38;#x30B5;&#38;#x30F3;&#38;#x30BF;&#38;#x30AF;&#38;#x30ED;&#38;#x30FC;&#38;#x30B9;&#38;quot; and you&#38;#39;ll end up with nothing but &lt;a href=&#34;http://en.wikipedia.org/wiki/Mojibake&#34;&gt;mojibake&lt;/a&gt; and coal in your stocking.&lt;/p&gt;

&lt;p&gt;By adding &lt;code&gt;use utf8::all&lt;/code&gt; to this program, &lt;code&gt;@ARGV&lt;/code&gt; is decoded from &lt;i&gt;octets&lt;/i&gt; into &lt;i&gt;characters&lt;/i&gt; and &lt;code&gt;STDOUT&lt;/code&gt; is encoded from &lt;i&gt;characters&lt;/i&gt; into &lt;i&gt;octets&lt;/i&gt; for you. That means the results will end up being &#38;quot;HI SANTA CLAUS!&#38;quot;, &#38;quot;HI P&#38;Egrave;RE NO&#38;Euml;L!&#38;quot;, and &#38;quot;HI &#38;#x30B5;&#38;#x30F3;&#38;#x30BF;&#38;#x30AF;&#38;#x30ED;&#38;#x30FC;&#38;#x30B9;!&#38;quot; Certainly a lot more respectable.&lt;/p&gt;

&lt;p&gt;This module is especially useful for one-liners, since fiddling with the encoding of &lt;code&gt;@ARGV&lt;/code&gt;, &lt;code&gt;STDIN&lt;/code&gt;, and &lt;code&gt;STDOUT&lt;/code&gt; takes a lot more code than simply using an &lt;a href=&#34;http://www.perladvent.org/2011/2011-12-05.html&#34;&gt;&lt;code&gt;-M&lt;/code&gt;&lt;/a&gt; on &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt;. Say we wanted to write a filter that converts its input to S&#38;#x1D0D;&#38;#x1D00;&#38;#x29F;&#38;#x29F;&#38;#x1D04;&#38;#x1D00;&#38;#x1D18;s. Note that we have to carefully set up the encoding of not only both &lt;code&gt;STDIN&lt;/code&gt; and &lt;code&gt;STDOUT&lt;/code&gt;, but also of the program itself. If we forget to tell Perl that our code is written in UTF-8 (by loading the special &lt;a href=&#34;https://metacpan.org/module/utf8&#34;&gt;utf8&lt;/a&gt; module), then our transliteration will produce garbage, because Perl will see the right-hand side of the &lt;code&gt;tr&lt;/code&gt; as 64 &lt;i&gt;octets&lt;/i&gt;, not 26 &lt;i&gt;characters&lt;/i&gt;.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;perl -Mutf8 -pe &#38;#39;BEGIN { binmode($_, &#38;quot;:utf8&#38;quot;) for STDIN, STDOUT }&lt;br /&gt;&#38;nbsp;&#38;nbsp;tr[a-z][&#38;#x1D00;&#38;#x299;&#38;#x1D04;&#38;#x1D05;&#38;#x1D07;&#38;#xA730;&#38;#x262;&#38;#x29C;&#38;#x26A;&#38;#x1D0A;&#38;#x1D0B;&#38;#x29F;&#38;#x1D0D;&#38;#x274;&#38;#x1D0F;&#38;#x1D18;Q&#38;#x280;s&#38;#x1D1B;&#38;#x1D1C;&#38;#x1D20;&#38;#x1D21;x&#38;#x28F;&#38;#x1D22;]&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If that looks like a lot to spring from your fingers every time you want to write a one-liner that handles Unicode correctly, it certainly is. That one-liner doesn&#38;#39;t even handle &lt;code&gt;STDERR&lt;/code&gt;, &lt;code&gt;@ARGV&lt;/code&gt;, or any additional file handles we might open!&lt;/p&gt;

&lt;p&gt;Instead, by simply declaring &lt;code&gt;-Mutf8::all&lt;/code&gt;, you don&#38;#39;t have to micromanage any of that.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;perl -Mutf8::all -pe &#38;#39;tr[a-z][&#38;#x1D00;&#38;#x299;&#38;#x1D04;&#38;#x1D05;&#38;#x1D07;&#38;#xA730;&#38;#x262;&#38;#x29C;&#38;#x26A;&#38;#x1D0A;&#38;#x1D0B;&#38;#x29F;&#38;#x1D0D;&#38;#x274;&#38;#x1D0F;&#38;#x1D18;Q&#38;#x280;s&#38;#x1D1B;&#38;#x1D1C;&#38;#x1D20;&#38;#x1D21;x&#38;#x28F;&#38;#x1D22;]&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;T&#38;#x29C;&#38;#x1D07; &#38;#xA730;&#38;#x1D1C;&#38;#x1D1B;&#38;#x1D1C;&#38;#x280;&#38;#x1D07; &#38;#x26A;s &#38;#x29C;&#38;#x1D07;&#38;#x280;&#38;#x1D07;!&lt;/p&gt;

&lt;h3 id=&#34;utf8::alls-reach&#34;&gt;&lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt;&#38;#39;s reach&lt;/h3&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; doesn&#38;#39;t cover all of the suggestions Tom Christiansen outlines in &lt;a href=&#34;http://stackoverflow.com/questions/6162484/why-does-modern-perl-avoid-utf-8-by-default/6163129#6163129&#34;&gt;his epic Stack Overflow post&lt;/a&gt; for basic Unicode support, but it does have open tickets for the features it misses! Right now (as of the upcoming 0.03), it&#38;#39;s only missing an automatic &lt;code&gt;&lt;a href=&#34;https://metacpan.org/module/feature#the-unicode_strings-feature&#34;&gt;unicode_strings&lt;/a&gt;&lt;/code&gt; and promoting encoding problems to fatal errors.&lt;/p&gt;

&lt;p&gt;There are also loads of cases &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; will never be able catch. Despite its name, there is simply no sane way to dictate that everything must be Unicode. There is too much existing code out there which will break if you change its basic assumptions. For example if you&#38;#39;re using &lt;a href=&#34;https://metacpan.org/module/DBD::SQLite&#34;&gt;DBD::SQLite&lt;/a&gt;, you&#38;#39;ll need to explicitly turn on UTF-8 handling like so:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBI&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;dbi:SQLite:dbname=$file&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;sqlite_unicode&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;There&#38;#39;s also nothing this module, or any module really, can do to magically fix your English-specific assumptions. If you perform a text-munging operation like &lt;code&gt;s/[0-9]//g&lt;/code&gt; then there&#38;#39;s no way to programmatically generalize that to Unicode. There are lots of other ways to write numerals besides the familiar Arabic digits, like &#38;#x2166;, &#38;#x4E07;, and &#38;#x17E7;, so a human with an understanding of the business requirements needs to decide which kinds of numerals to include and which kinds to exclude. There&#38;#39;s no way a program can make the right choice for you.&lt;/p&gt;

&lt;p&gt;All that said, &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; is still a mighty useful tool, especially for one-liners and small scripts, since it gets you 90% of the way there. If you&#38;#39;re still reeling from all this, let &lt;a href=&#34;https://metacpan.org/module/utf8::all&#34;&gt;utf8::all&lt;/a&gt; serve as your first toe into the vast ocean of Unicode. It&#38;#39;s (nearly) 2012 and the world is growing only more and more interconnected, so you are running out of excuses for not learning about how to deal with encodings.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Encode&#34;&gt;Encode&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Encode::DoubleEncodedUTF8&#34;&gt;Encode::DoubleEncodedUTF8&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Unicode::Tussle&#34;&gt;Unicode::Tussle&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/perl5i&#34;&gt;perl5i&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://98.245.80.27/tcpc/OSCON2011/index.html&#34;&gt;http://98.245.80.27/tcpc/OSCON2011/index.html&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-21T00:00:00-05:00</updated><category term="Perl"/><author><name>Shawn M Moore</name></author></entry><entry><title>Revisiting Test::Routine</title><link href="http://perladvent.org/2011/2011-12-20.html"/><id>http://perladvent.org/2011/2011-12-20.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Back in September 2010, I was still actively working on my &lt;a href=&#34;https://metacpan.org/module/MooseX::Declare&#34;&gt;MooseX::Declare&lt;/a&gt; inspired and &lt;a href=&#34;https://metacpan.org/module/Devel::Declare&#34;&gt;Devel::Declare&lt;/a&gt; powered layer over &lt;a href=&#34;https://metacpan.org/module/Test::Class&#34;&gt;Test::Class&lt;/a&gt;; Test::Class::Sugar and was feeling some pain as I tried to extend it. I was struggling to combine the xUnit style behaviour of Test::Class with &lt;a href=&#34;https://metacpan.org/module/Moose&#34;&gt;Moose&lt;/a&gt;&#38;#39;s expressive tools for declaring attributes and generally writing object oriented code. I don&#38;#39;t want to go into the details (because I&#38;#39;ve mercifully forgotten them), but I couldn&#38;#39;t see a way to make Test::Class&#38;#39;s innards compatible with Moose&#38;#39;s innards.&lt;/p&gt;

&lt;p&gt;So, when a message from rjbs appeared in my IRC client pointing me at his Moosey testing framework, Test::Routine, it appeared at the most opportune moment possible. You may have noticed that Test::Class::Sugar hasn&#38;#39;t been updated in a long time - that&#38;#39;s because I&#38;#39;ve switched all my testing to Test::Routine.&lt;/p&gt;

&lt;h3 id=&#34;Wrapping-my-head-around-Test::Routine&#34;&gt;Wrapping my head around Test::Routine&lt;/h3&gt;

&lt;p&gt;When I first started playing with Test::Routine there was one thing I found rather frustrating. In xUnit style testing, test isolation (a &lt;i&gt;very&lt;/i&gt; good thing) is isolated because each test is run with a fresh instance of the test class. It&#38;#39;s much harder to have your tests getting tangled when you do this. However, consider something like:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::Routine&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::More&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;a_big_immutable_fixture&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ro&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;lazy_builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_build_a_big_immutable_fixture&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xml&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;fetch_document_over_a_slow_connection&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;munge_10megs_of&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$xml&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;this&#38;quot;&lt;/span&gt;      &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;that&#38;quot;&lt;/span&gt;      &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;the other&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;run_me&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;done_testing&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If Test::Routine worked like xUnit, that big fixture would make the test suite slow. The usual way fixture building is done in xUnit style classes is that the test suite calls &lt;code&gt;setup&lt;/code&gt; before it runs a test and &lt;code&gt;teardown&lt;/code&gt; after. With Test::Routine I found that I could dispense with an explicit setup phase by declaring my attributes with the &lt;code&gt;lazy_build&lt;/code&gt; flag and using builders to set up my attributes and an &lt;code&gt;after&lt;/code&gt; hook to clear up any attributes that needed resetting. So I might do:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::Routine&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::More&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;big_immutable_fixture&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ro&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;lazy_build&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;something_mutable&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;rw&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;lazy_build&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_build_a_big_immutable_fixture&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_build_something_mutable&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;run_test&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;clear_something_mutable&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Now, this is all very well, and it certainly works, but it&#38;#39;s not very declarative. What would be rather handy, I said to Rik, would be if I could write something like:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;something_mutable&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;rw&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;lazy_build&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;auto_clear&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;and let the &lt;code&gt;after run_test&lt;/code&gt; part be handled automatically by Test::Routine. Rik agreed that that would be cool, but that he wasn&#38;#39;t in a hurry to get it written. Nor was I. And there we left it.&lt;/p&gt;

&lt;h3 id=&#34;Its-Advent-all-over-again&#34;&gt;It&#38;#39;s Advent all over again&lt;/h3&gt;

&lt;p&gt;Spool forward to now. Rik&#38;#39;s written about Test::Routine in his 2010 advent calendar and the world knows about it. But in 2011, he&#38;#39;s not just plotting an Advent calendar, he&#38;#39;s also the recently crowned (on Halloween, natch) Perl Pumpking and he can&#38;#39;t just dash off 25 articles about cool perl modules like he has done for the past couple of years. Once again, a chat window opens up in my IRC client.&lt;/p&gt;

&lt;p&gt;&#38;quot;Hey, Piers, would you like to write an article for this year&#38;#39;s Advent calendar?&#38;quot;&lt;/p&gt;

&lt;p&gt;Well... there&#38;#39;s an invitation you take very seriously.&lt;/p&gt;

&lt;h3 id=&#34;Not-very-many-lines-of-code-later&#34;&gt;Not very many lines of code later&lt;/h3&gt;

&lt;p&gt;Do you know how hard Moose rocks? Really? In one evening&#38;#39;s hacking, most of which was spent reading documentation and a couple of different MooseX modules to see how it was done, I can now write:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;br /&gt;23:&#38;nbsp;&lt;br /&gt;24:&#38;nbsp;&lt;br /&gt;25:&#38;nbsp;&lt;br /&gt;26:&#38;nbsp;&lt;br /&gt;27:&#38;nbsp;&lt;br /&gt;28:&#38;nbsp;&lt;br /&gt;29:&#38;nbsp;&lt;br /&gt;30:&#38;nbsp;&lt;br /&gt;31:&#38;nbsp;&lt;br /&gt;32:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::Routine::xUnitish&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::Routine::Util&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Test::More&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;namespace::autoclean&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;rw&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;isa&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Int&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;default&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;auto_clear&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;first&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Always starting from zero&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;And going to 1&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;second&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Always starting from zero&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;counter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;And going to 1&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;run_me&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;done_testing&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;And it all Just Works. The code isn&#38;#39;t on the main line of Test::Routine. The documentation is laughably non-existent and I&#38;#39;m not entirely sure that the implementation is properly robust, but it works. If you&#38;#39;re interested in having a play, you can pull the latest version from my &lt;a href=&#34;http://github.com/pdcawley/Test-Routine&#34;&gt;Test::Routine github fork&lt;/a&gt;. Enjoy yourselves.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Test::Routine&#34;&gt;Test::Routine&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Test::Class&#34;&gt;Test::Class&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/pdcawley/Test-Routine/blob/master/lib/Test/Routine/xUnitish.pm&#34;&gt;Test::Routine::xUnitish&lt;/a&gt; (on GitHub)&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-20T00:00:00-05:00</updated><category term="Perl"/><author><name>Piers Cawley</name></author></entry><entry><title>Process ALL the FILES!</title><link href="http://perladvent.org/2011/2011-12-19.html"/><id>http://perladvent.org/2011/2011-12-19.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Theres-More-Than-One-Way-to-Find-Files&#34;&gt;There&#38;#39;s More Than One Way to Find Files&lt;/h2&gt;

&lt;h3 id=&#34;File::Find&#34;&gt;File::Find&lt;/h3&gt;

&lt;p&gt;The very first release of perl 5 included &lt;a href=&#34;https://metacpan.org/module/File::Find&#34;&gt;File::Find&lt;/a&gt;. It provided a mechanism for searching a file hierarchy for files and, presumably, doing stuff with them. You use it like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;File::Find&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;follow&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# follow symlinks&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;wanted&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-d&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$File::Find::dir&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;m{(?:^|/)tmp$}&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;        # skip tmp dirs everywhere, do not descend into them&lt;br /&gt;&lt;/span&gt;        &lt;span class=&#34;symbol&#34;&gt;$File::Find::prune&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-s&lt;/span&gt;   &lt;span class=&#34;operator&#34;&gt;&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1_000_000&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# ignore small files&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-M&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;lt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;86_400&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;    &lt;span class=&#34;comment&#34;&gt;# files not touched today&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;process_big_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# start processing in cwd&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Simple, right?&lt;/p&gt;

&lt;p&gt;Like many libraries that have their origins in the early days of Perl 5, its interface can seem a bit weird today. The usual complaint is that the &lt;code&gt;wanted&lt;/code&gt; argument is not actually a test as to whether we want the file. It&#38;#39;s a combination of testing for whether we want a file, whether we want to descend into a directory, and doing whatever we want to do.&lt;/p&gt;

&lt;p&gt;Oh, and the whole thing works with package variables and used to have a bunch of problems with reentrancy.&lt;/p&gt;

&lt;h3 id=&#34;File::Find::Rule&#34;&gt;File::Find::Rule&lt;/h3&gt;

&lt;p&gt;Quite a while ago, we got a much simpler API for doing this sort of thing in &lt;a href=&#34;https://metacpan.org/module/File::Find::Rule&#34;&gt;File::Find::Rule&lt;/a&gt;. It let you build up a query that would find the files you wanted, and then you could iterate over them doing stuff. It got a nice separation of &#38;quot;find&#38;quot; and &#38;quot;do,&#38;quot; and as a bonus, threw in a lot of nice methods for writing your query quickly.&lt;/p&gt;

&lt;p&gt;We&#38;#39;d write the above something like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;File::Find::Rule&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;File::Find::Rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;regexp&#34;&gt;qr{(?:^|/)tmp$}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;prune&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;discard&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;&#38;gt;1000000&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-M&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;lt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;86_400&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;})&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iter&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;process_big_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This looks a lot simpler &#38;ndash; at least to me. There are a whole heap of extra simple rules, too, and you can add your own. I&#38;#39;ve used File::Find::Rule happily for years, except for the one case where it becomes &lt;i&gt;completely intolerable&lt;/i&gt;. Allow me to demonstrate:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ time perl -MFile::Find -e &#38;#39;find({ wanted =&#38;gt; sub { die $_ if -f $_ } }, &#38;quot;/&#38;quot;)&#38;#39;&lt;br /&gt;0.03s user 0.01s system 70% cpu 0.045 total&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This program takes nearly no time at all to run. It starts looking for files in &lt;i&gt;/&lt;/i&gt;, finds something, and the &lt;code&gt;wanted&lt;/code&gt; coderef exits immediately.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ time perl -MFile::Find::Rule -e &#38;#39;my $iter = File::Find::Rule-&#38;gt;start(&#38;quot;/&#38;quot;); die $iter-&#38;gt;()&#38;#39;&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;(okay, I finally killed it)&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;File::Find::Rule actually compiles your rules down to use File::Find, but it loses one of File::Find&#38;#39;s key properties: it is not lazy. Even if you ask for an iterator, it slurps up all the files, then iterates over that list. If you want to look through millions of files, this is just not going to cut it.&lt;/p&gt;

&lt;p&gt;That doesn&#38;#39;t mean you need to go back to File::Find, though.&lt;/p&gt;

&lt;h3 id=&#34;Path::Class::Rule&#34;&gt;Path::Class::Rule&lt;/h3&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ time perl -MPath::Class::Rule -e &#38;#39;my $iter = Path::Class::Rule-&#38;gt;new-&#38;gt;file-&#38;gt;iter(&#38;quot;/&#38;quot;); die $iter-&#38;gt;()&#38;#39;&lt;br /&gt;0.09s user 0.01s system 86% cpu 0.117 total&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Okay, so it&#38;#39;s fast. What is it?&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Path::Class::Rule&#34;&gt;Path::Class::Rule&lt;/a&gt; is yet another file finder, with an interface very much like that of File::Find::Rule, with two key differences: it provides &lt;a href=&#34;https://metacpan.org/module/Path::Class&#34;&gt;Path::Class&lt;/a&gt; objects instead of filename strings, and its iterator is actually lazy.&lt;/p&gt;

&lt;p&gt;We could write our search as:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Path::Class::Rule&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Path::Class::Rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;skip&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;regexp&#34;&gt;qr{(?:^|/)tmp$}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;&#38;gt;1000000&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;and&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-M&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;lt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;86_400&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iter&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rule&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;iter&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;.&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;process_big_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$_&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;There are a bunch of little differences between File::Find::Rule and Path::Class::Rule, but it&#38;#39;s worth getting over them so that when you need to take your program and run it against that huge set of files you accidentally let accumulate under &lt;i&gt;/var&lt;/i&gt; because you thought that the other guy was taking care of it (I mean, it&#38;#39;s pretty much his responsibility, right?)... well, you just want the program to work without having to read the whole filesystem into memory first, right?&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Path::Class::Rule&#34;&gt;Path::Class::Rule&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Path::Class&#34;&gt;Path::Class&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/File::Find&#34;&gt;File::Find&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://www.perladvent.org/2000/16/&#34;&gt;File::Find on the Perl Advent Calendar&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/File::Find::Rule&#34;&gt;File::Find::Rule&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;http://www.perladvent.org/2002/11th/&#34;&gt;File::Find::Rule on the Perl Advent Calendar&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/File::Next&#34;&gt;File::Next&lt;/a&gt; - another file finder that is quite nice&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-19T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Munge All the Filenames!</title><link href="http://perladvent.org/2011/2011-12-18.html"/><id>http://perladvent.org/2011/2011-12-18.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;A-Shameful-Admission&#34;&gt;A Shameful Admission&lt;/h2&gt;

&lt;p&gt;It has come to pass many times that I&#38;#39;ve needed to rename a bunch of files. I had a bunch of strategies for doing this, and I never picked one and stuck to using it. I &lt;i&gt;certainly&lt;/i&gt; never build a reusable tool for it, which meant that every time I did it, I screwed things up in a new and exciting way.&lt;/p&gt;

&lt;p&gt;Sometimes a one-liner in shell would do it:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synStatement&#34;&gt;for &lt;/span&gt;f &lt;span class=&#34;synStatement&#34;&gt;in&lt;/span&gt; *.txt; &lt;span class=&#34;synSpecial&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;mv&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;.old&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Or maybe:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synStatement&#34;&gt;for &lt;/span&gt;f &lt;span class=&#34;synStatement&#34;&gt;in&lt;/span&gt; *.txt; &lt;span class=&#34;synSpecial&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;BASE&lt;/span&gt;=&lt;span class=&#34;synPreProc&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;basename &lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt; .txt&lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;mv&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;$f&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt;&lt;span class=&#34;synPreProc&#34;&gt;$BASE&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;.yaml&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#38;quot;&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Other times, I&#38;#39;d resort to Perl:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;autodie&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(rename)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@files&lt;/span&gt;   &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;grep&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-f&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;lt;*&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;@files&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/^([0-9]+)/sprintf &#39;%4u&#39;, $1/e&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;rename&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Actually, I am relieved to note that I can&#38;#39;t even easily show what I usually did, which was just deplorable. I&#38;#39;d run Vim and do something like &lt;code&gt;:r !find . -type f&lt;/code&gt; to get a list of files, then do some &lt;code&gt;:v/.../d&lt;/code&gt; to delete files I didn&#38;#39;t care to rename, then maybe put it in a &lt;code&gt;__DATA__&lt;/code&gt; section to iterate over or maybe use a block yank-and-put to build up a file that looked like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;file1.pdf         &#38;quot;File 01.pdf&#38;quot;&lt;br /&gt;file2.pdf         &#38;quot;File 02.pdf&#38;quot;&lt;br /&gt;file10.pdf        &#38;quot;File 10.pdf&#38;quot;&lt;br /&gt;file18.pdf        &#38;quot;File 18.pdf&#38;quot;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Then I could just &lt;code&gt;:%s/^/mv /&lt;/code&gt; to put a &lt;code&gt;mv&lt;/code&gt; at the front of every line and pipe it through &lt;code&gt;sh&lt;/code&gt;! Seriously, &lt;i&gt;I did this&lt;/i&gt;. But I&#38;#39;ve gotten better. Now I use &lt;a href=&#34;https://metacpan.org/module/rename&#34;&gt;rename&lt;/a&gt;.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;rename &#38;#39;$_ = ucfirst; s/([0-9]+)/sprintf &#38;quot;%02u&#38;quot;, $1/e;&#38;#39; *.pdf&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;I love writing one-liners, but I always get them wrong. For example, that one above has a bug. With lots of one-liners, I can just run them over and over until I get it right. When renaming files, though, you don&#38;#39;t want to actually do it until you have it right &#38;ndash; so there&#38;#39;s the &lt;code&gt;-n&lt;/code&gt; switch to do a dry run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ rename -n &#38;#39;$_ = ucfirst; s/([0-9]+)/sprintf &#38;quot;%02u&#38;quot;, $1/e;&#38;#39; *.pdf
  rename file1.pdf File01.pdf
  rename file10.pdf File10.pdf
  rename file18.pdf File18.pdf
  rename file2.pdf File02.pdf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oops. I need to add whitespace.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ rename -n &#38;#39;$_ = ucfirst; s/ *([0-9]+)/sprintf &#38;quot; %02u&#38;quot;, $1/e;&#38;#39; *.pdf
  rename file1.pdf File 01.pdf
  rename file10.pdf File 10.pdf
  rename file18.pdf File 18.pdf
  rename file2.pdf File 02.pdf&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Great! Drop the &lt;code&gt;-n&lt;/code&gt; and our files get renamed!&lt;/p&gt;

&lt;p&gt;If you need to do something more complicated &#38;ndash; like keep a counter to number your files, you can write a whole subroutine in a &#38;quot;real&#38;quot; program:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;File::Rename&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@files&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@ARGV&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;no files given!&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$i&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$width&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@files&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;File::Rename::rename&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;@files&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/^/sprintf &#39;%0*u - &#39;, $width, $i++/e&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/rename&#34;&gt;rename&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/File::Rename&#34;&gt;File::Rename&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/mfn&#34;&gt;mfn&lt;/a&gt; is a specialized renamer for dealing in bulk with terrible filenames&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://socialtext.net/perl5/prename&#34;&gt;a list of other Perl renamers&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-18T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>There is No Try</title><link href="http://perladvent.org/2011/2011-12-17.html"/><id>http://perladvent.org/2011/2011-12-17.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;eval-Stinks&#34;&gt;&lt;code&gt;eval&lt;/code&gt; Stinks&lt;/h2&gt;

&lt;p&gt;This is a pretty common pattern of code:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;magic&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;set_last_error&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;couldn&#39;t get stuff computed: $@&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;In other words, try to call some method on &lt;code&gt;$self&lt;/code&gt;&#38;#39;s helper object. If it fails, set an error and return &lt;code&gt;undef&lt;/code&gt;. Otherwise, return the result we got. You can find code like this all over the place, and unfortunately, it&#38;#39;s got problems.&lt;/p&gt;

&lt;p&gt;The most horrible, and possibly well known, is that &lt;code&gt;$@&lt;/code&gt; being set isn&#38;#39;t the right way to check for &lt;code&gt;eval&lt;/code&gt; failing. (Let&#38;#39;s not worry about the pathological case of someone throwing a false exception object. That&#38;#39;s just sick.)&lt;/p&gt;

&lt;p&gt;The real reason is that until recently, &lt;code&gt;$@&lt;/code&gt; could get easily clobbered by action at a distance. For example, look at the code again:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It&#38;#39;s calling &lt;code&gt;computation_helper&lt;/code&gt; which might look like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Computation::Helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;helper_for&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It sets up some helper object that we can throw away when we&#38;#39;re done. We call its &lt;code&gt;compute_stuff&lt;/code&gt; method, which dies. At this point, &lt;code&gt;eval&lt;/code&gt; starts to return false, with &lt;code&gt;$@&lt;/code&gt; set to that exception message. Unfortunately, little known to us, this code exists:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Computation::Helper&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DESTROY&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...and it&#38;#39;s going to clobber our &lt;code&gt;$@&lt;/code&gt; when the helper object gets destroyed &#38;ndash; and that&#38;#39;s going to happen once the &lt;code&gt;eval&lt;/code&gt; block is done and the helper object is no longer referenced by anything. Instead of testing for &lt;code&gt;$@&lt;/code&gt;, we should test for a false return from &lt;code&gt;eval&lt;/code&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # we died! set last_error, etc.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This isn&#38;#39;t any good, either, though. What if &lt;code&gt;compute_stuff&lt;/code&gt; can actually return false, or more specifically the empty string? We need to rewrite to force &lt;code&gt;eval&lt;/code&gt;&#38;#39;s hand:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ok&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ok&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # we died! set last_error, etc.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Now we know that &lt;code&gt;eval&lt;/code&gt; will always return &lt;code&gt;1&lt;/code&gt; unless it fails. This means we need to move the assignment to &lt;code&gt;$result&lt;/code&gt; inside the eval, and we need to move the declaration to an new, earlier statement.&lt;/p&gt;

&lt;p&gt;Finally, to keep our eval from clobbering anybody else&#38;#39;s &lt;code&gt;$@&lt;/code&gt; in the future, we need to localize. In the end, our code ends up as:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ok&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ok&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$error&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$@&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;unknown error&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$@&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;set_last_error&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;couldn&#39;t get stuff computed: $error&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Even if not a &lt;i&gt;huge&lt;/i&gt; increase in the code needed for the operation, it&#38;#39;s a bunch of magic to remember every time. If you don&#38;#39;t do this sort of thing, though, you&#38;#39;ve got a big opening for horrible error-handling problems.&lt;/p&gt;

&lt;h2 id=&#34;Two-Solutions&#34;&gt;Two Solutions&lt;/h2&gt;

&lt;p&gt;It&#38;#39;s worth noting that these problems are greatly lessened in perl 5.14, where our hypothetical &lt;code&gt;DESTROY&lt;/code&gt; method would not have clobbered the outer &lt;code&gt;$@&lt;/code&gt;. If you can use 5.14, you should, and this is one very good reason.&lt;/p&gt;

&lt;p&gt;That still leaves a bunch of boilerplate, though. This is why &lt;a href=&#34;https://metacpan.org/module/Try::Tiny&#34;&gt;Try::Tiny&lt;/a&gt; has become so popular. Unlike many of the other, more feature-rich try/catch systems on the CPAN, Try::Tiny focuses on doing just the minimum needed to avoid the boilerplate above. For example, we&#38;#39;d write the code above as:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Try::Tiny&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$error&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;unknown error&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$_&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;set_last_error&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;couldn&#39;t get stuff computed: $error&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It encapsulates the localization of the error variable and the addition of the constant true value to check for. The &lt;code&gt;catch&lt;/code&gt; block is only entered if the &lt;code&gt;try&lt;/code&gt; block died, and the exception thrown is in &lt;code&gt;$_&lt;/code&gt; (and &lt;code&gt;$_[0]&lt;/code&gt;). Simple!&lt;/p&gt;

&lt;h2 id=&#34;Extra-Sugar&#34;&gt;Extra Sugar&lt;/h2&gt;

&lt;p&gt;Try::Tiny also provides one more helper: &lt;code&gt;finally&lt;/code&gt;. It lets you provide a block (or many blocks) of code to be run after the &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt;, no matter whether there was an error:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Try::Tiny&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$start&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Time::HiRes::time&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;computation_helper&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;compute_stuff&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$error&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;unknown error&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$_&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;set_last_error&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;couldn&#39;t get stuff computed: $error&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;undef&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;finally&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$failed&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$end&lt;/span&gt;  &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Time::HiRes::time&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;warn&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;sprintf&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;took %f seconds to %s&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$end&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$start&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$failed&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;fail&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;succeed&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;You can tell whether the &lt;code&gt;try&lt;/code&gt; block failed by whether there are any elements in &lt;code&gt;@_&lt;/code&gt;. Even if somehow the contents of &lt;code&gt;$@&lt;/code&gt; couldn&#38;#39;t be preserved, you&#38;#39;ll find an undef in the argument list if the try failed. Otherwise, it will be empty. You can supply as many try blocks as you want.&lt;/p&gt;

&lt;p&gt;Try::Tiny doesn&#38;#39;t do much, but it nicely packages up a pattern that&#38;#39;s important to use and really boring to type out every time. Not only does it save you from having to remember the details each time, but it gives you an interface that&#38;#39;s easier to write and skim, too. Use it!&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Try::Tiny&#34;&gt;Try::Tiny&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-17T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>All Your Documentation, Even Offline</title><link href="http://perladvent.org/2011/2011-12-16.html"/><id>http://perladvent.org/2011/2011-12-16.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;perldoc.perl.org&#34;&gt;&lt;code&gt;perldoc.perl.org&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;A few years ago, &lt;a href=&#34;http://search.cpan.org/~jonallen/&#34;&gt;Jon Allen&lt;/a&gt; set up &lt;code&gt;&lt;a href=&#34;http://perldoc.perl.org&#34;&gt;perldoc.perl.org&lt;/a&gt;&lt;/code&gt;, a site where you could browse the core Perl 5 documentation. A few sites existed for this kind of thing, including &lt;code&gt;search.cpan.org&lt;/code&gt;, but Jon&#38;#39;s site blew the doors off of them. It had good search, nice styling, syntax highlighting, and lots of other little details that made it fantastic. It kept getting better, but the big question people kept asking was, &#38;quot;When can I run my own?&#38;quot; (Some people prefer to read all their documentation in the terminal, but these people are weirdos and can use &lt;a href=&#34;http://perladvent.org/2011/2011-12-15.html&#34;&gt;different tools&lt;/a&gt; for that.)&lt;/p&gt;

&lt;p&gt;Even with the Internet available almost anywhere, being able to work offline is a huge win. If your key reference materials &#38;ndash; like the documentation of your programming language itself &#38;ndash; go from being nicely available offline (via &lt;code&gt;&lt;a href=&#34;http://perladvent.org/2011/2011-12-15.html&#34;&gt;cpandoc&lt;/a&gt;&lt;/code&gt;) to only being available when you can access web pages, you&#38;#39;re in line for some hard times. Having the man pages available as HTML is really tempting, though. Not only do they look quite nice, but their interlinking becomes very useful. &lt;a href=&#34;https://metacpan.org/module/perlpod&#34;&gt;Pod&lt;/a&gt; is a format with decent facilities for linking to other documents, but the &lt;code&gt;perldoc&lt;/code&gt; makes those links pretty worthless. In HTML, they become an asset.&lt;/p&gt;

&lt;p&gt;Fortunately for everyone who was desperate to get hooked on the perldoc server, Jon soon released &lt;a href=&#34;https://metacpan.org/module/Perldoc::Server&#34;&gt;Perldoc::Server&lt;/a&gt;. Not only did it let you run your own copy of &lt;code&gt;perldoc.perl.org&lt;/code&gt;, but it went even further. It serves up nicely formatted web pages for all the documentation of all modules you&#38;#39;ve got installed in your Perl environment.&lt;/p&gt;

&lt;p&gt;It&#38;#39;s easy to see how it all works:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ eval `perl -Mlocal::lib=~/local/perldoc`&lt;br /&gt;$ cpanm Perldoc::Server&lt;br /&gt;&#38;hellip;&lt;br /&gt;29 distributions installed&lt;br /&gt;$ perldoc-server&lt;br /&gt;&#38;hellip;&lt;br /&gt;Now listening on http://localhost:7375/&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...and you can fire up your web browser, hit that URL, and see all the docs in your &lt;code&gt;@INC&lt;/code&gt; presented in glorious HTML.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Perldoc::Server&#34;&gt;Perldoc::Server&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Pod::Cpandoc&#34;&gt;Pod::Cpandoc&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Pod::Perldoc&#34;&gt;Pod::Perldoc&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-16T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Install Even Less</title><link href="http://perladvent.org/2011/2011-12-15.html"/><id>http://perladvent.org/2011/2011-12-15.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Reading-the-Friendly-Manual&#34;&gt;Reading the Friendly Manual&lt;/h2&gt;

&lt;p&gt;So, when you want to just play around with a module, &lt;a href=&#34;http://perladvent.org/2011/2011-12-01.html&#34;&gt;local::lib&lt;/a&gt; is a good way to install libraries in a quick, disposable way that doesn&#38;#39;t affect your global development environment. Sometimes, though, you don&#38;#39;t even need to play around. You just want to look at the docs for the code someone suggested but that you haven&#38;#39;t yet installed.&lt;/p&gt;

&lt;p&gt;A lot of people would switch over to a web browser, but not me. I&#38;#39;m used to reading Perl documentation in the terminal, and reading it elsewhere ends up giving me a confused feeling. In the past, I used to just install the code (in a local::lib compartment once I knew about it) and then run &lt;code&gt;perldoc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, some people &lt;i&gt;prefer&lt;/i&gt; reading their docs on the web. There are other tools for weirdos like that. Me, I like &lt;code&gt;&lt;a href=&#34;https://metacpan.org/module/Pod::Cpandoc&#34;&gt;cpandoc&lt;/a&gt;&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cpandoc&lt;/code&gt; works &lt;i&gt;almost exactly&lt;/i&gt; like &lt;code&gt;perldoc&lt;/code&gt;, with a big change that makes it even better. If &lt;code&gt;cpandoc&lt;/code&gt; can&#38;#39;t find the library you asked for in your system&#38;#39;s Perl environment, it will get it &#38;ndash; just the documentation &#38;ndash; from the CPAN and format that instead.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ perldoc MooseX::Iterator
  No documentation found for &#38;quot;MooseX::Iterator&#38;quot;.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh no! Will I have to press Cmd-Tab and go to my web browser? Or download the library and look at its tarball&#38;#39;s contents? No! I can just...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ cpandoc MooseX::Iterator
  [ ... and the pager runs, showing me the documentation! ]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Truth be told, though, this isn&#38;#39;t where it shines for me. I like that it provides all the same options as &lt;code&gt;perldoc&lt;/code&gt;. Specifically, it has the &lt;code&gt;-m&lt;/code&gt; option, to view the source. When someone on IRC has questions about how some module they&#38;#39;re trying to use works, I just run...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ cpandoc -m Some::Stupid::Module&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...and I get the source of the code in question, whether or not I already have it locally.&lt;/p&gt;

&lt;p&gt;And, well, actually that&#38;#39;s not true either. Since &lt;code&gt;cpandoc&lt;/code&gt; is just like &lt;code&gt;perldoc&lt;/code&gt;, I made a shell alias. When I type &lt;code&gt;perldoc&lt;/code&gt; &#38;ndash; as I always do, since it&#38;#39;s burned into my muscle memory &#38;ndash; I get &lt;code&gt;cpandoc&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Pod::Cpandoc&#34;&gt;Pod::Cpandoc&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Pod::Perldoc&#34;&gt;Pod::Perldoc&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-15T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title type="html">Don&#38;#39;t Get Kickbanned</title><link href="http://perladvent.org/2011/2011-12-14.html"/><id>http://perladvent.org/2011/2011-12-14.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;IRC-is-great-&#34;&gt;IRC is great!&lt;/h2&gt;

&lt;p&gt;Over the years, I&#38;#39;ve heard a lot of loose talk about how IRC is a cesspool of bad attitudes, filthy language, and unhelpful people who would sooner stab you in the face than look at your problem code. This is entirely untrue!&lt;/p&gt;

&lt;p&gt;Well, at any rate, it&#38;#39;s not &lt;i&gt;entirely&lt;/i&gt; true. Those people would probably like to stab you in the face, but only if you give them an excuse. Probably the biggest offense you can commit &#38;ndash; other than just being a &lt;a href=&#34;http://foldoc.org/Known+Lazy+Bastard&#34;&gt;known lazy bastard&lt;/a&gt; &#38;ndash; is trying to paste your whole six thousand line program to the channel.&lt;/p&gt;

&lt;p&gt;You have to communicate the program, though, and programs can be big. Even if you boil your problem down to a simple test case, it might be twenty lines, and a twenty line paste will still get you kicked off the channel pretty darn fast. To work around the problem, most IRC channels have paste bins. A paste bin is a web site where you can paste your huge code listing or exception report so that you don&#38;#39;t have to paste it to IRC. Some paste bins have IRC bots that report to the channel that you just pasted something. Others provide you with a URL to a pretty page showing your code listing.&lt;/p&gt;

&lt;h2 id=&#34;but-pasting-into-a-web-browser-is-hard-&#34;&gt;...but pasting into a web browser is &lt;i&gt;hard&lt;/i&gt;!&lt;/h2&gt;

&lt;p&gt;If you boil your code down to a twenty line test case, it&#38;#39;s pretty easy to copy and paste into your web browser. When you really can&#38;#39;t reduce things below a few hundred lines, it gets more complicated &#38;ndash; especially if you&#38;#39;re editing things in a terminal, over ssh, in screen. You could copy the file around, open it in something with a &#38;quot;Select All&#38;quot; option, and so on&#38;hellip; or you could just enjoy yet another minor improvement to your life brought to you by unix pipes and Perl.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::Nopaste&#34;&gt;App::Nopaste&lt;/a&gt; provides &lt;code&gt;nopaste&lt;/code&gt;, a simple command-line program that takes standard input, writes it to a paste bin, and prints the URL where your paste can be found. It is the &lt;a href=&#34;https://metacpan.org/module/DBI&#34;&gt;DBI&lt;/a&gt; of paste bins, with multiple backends for whichever paste bin you like best. If your favorite paste bin isn&#38;#39;t working, it will fall back to backup choices. It works with named files or standard input:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~/tmp$ nopaste bangbang.pl&lt;br /&gt;http://gist.github.com/1350212&lt;br /&gt;&lt;br /&gt;~/tmp$ ./bangbang.pl | nopaste&lt;br /&gt;http://gist.github.com/1350213&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;As you can see here, I use &lt;code&gt;nopaste&lt;/code&gt; to paste to &lt;a href=&#34;http://gist.github.com/&#34;&gt;Gist&lt;/a&gt;, Github&#38;#39;s paste bin. Each paste into Gist becomes a Git repository, and can have multiple revisions, multiple files, and comments. It&#38;#39;s &lt;i&gt;really&lt;/i&gt; nice. To make sure my Gist pastes are associated with my Github account, so I can edit (and delete!) them, I just make sure my &lt;a href=&#34;http://help.github.com/set-your-user-name-email-and-github-token/&#34;&gt;Github credentials&lt;/a&gt; are set in my &lt;i&gt;~/.gitconfig&lt;/i&gt; file and it all works:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synSpecial&#34;&gt;[github]&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synType&#34;&gt;user  =&lt;/span&gt; rjbs&lt;br /&gt;&lt;span class=&#34;synType&#34;&gt;token =&lt;/span&gt; 23bea31203eba10ea90987876faeeda72&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Unfortunately, Github isn&#38;#39;t always up. Its availability is pretty good, but when I&#38;#39;m flailing and losing my patience so much with a bug that I&#38;#39;ve gone into a horrible place like &lt;i&gt;IRC&lt;/i&gt; to look for help, the last thing I want is to find out that my paste bin is broken, too. It&#38;#39;s easy to configure fallbacks. I have this line in my &lt;i&gt;.zshrc&lt;/i&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synStatement&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt; NOPASTE_SERVICES=&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;Gist Pastie Snitch Shadowcat&lt;/span&gt;&lt;span class=&#34;synStatement&#34;&gt;&#39;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;When Gist isn&#38;#39;t working, &lt;code&gt;nopaste&lt;/code&gt; will try a few more fallbacks, one of which is almost certain to work.&lt;/p&gt;

&lt;h2 id=&#34;Options-options-options-&#34;&gt;Options, options, options!&lt;/h2&gt;

&lt;p&gt;Gist doesn&#38;#39;t do IRC announcements of pastes, but lots of other paste bins do, so you need a way to tell &lt;code&gt;nopaste&lt;/code&gt; where to announce it. There are switches for that.&lt;/p&gt;

&lt;p&gt;With Gist, you&#38;#39;ll need to copy and paste the URL into IRC by hand &#38;ndash; but if you install &lt;a href=&#34;https://metacpan.org/module/Clipboard&#34;&gt;Clipboard&lt;/a&gt; and use &lt;code&gt;--copy&lt;/code&gt;, &lt;code&gt;nopaste&lt;/code&gt; will copy the URL to the clipboard automatically. You can open the URL automatically, mark the paste as private, or set other data about your paste so that it looks just right.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::Nopaste&#34;&gt;App::Nopaste&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Clipboard&#34;&gt;Clipboard&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Browser::Open&#34;&gt;Browser::Open&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-14T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>The new /r flag</title><link href="http://perladvent.org/2011/2011-12-13.html"/><id>http://perladvent.org/2011/2011-12-13.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Perl 5.14 introduced a new feature for the substitution operator to return a modified string while leaving the original alone. Normally, the substitution operator changes the bound string (if it matches) and returns the count of the number of substitutions:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$string&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If you didn&#38;#39;t want to change the string, you had to create a new one, often leading to this idiom:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$old&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This way, &lt;code&gt;$new&lt;/code&gt; gets a copy and is actually the target of the &lt;code&gt;s///&lt;/code&gt;. Instead of that, you can use the new &lt;code&gt;/r&lt;/code&gt; flag. That idiom then changes to this similar, but different statement:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$old&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/gr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This binds to &lt;code&gt;$old&lt;/code&gt; and returns the modified string to store in &lt;code&gt;$new&lt;/code&gt;. Working out the precedence, it looks like the parentheses have shifted:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$old&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/gr&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This turns out to be much more useful inside a &lt;code&gt;map&lt;/code&gt;, where it&#38;#39;s easy to forget that you don&#38;#39;t get the modified string back:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/g&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@old&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;After your &lt;code&gt;@new&lt;/code&gt; fills with &lt;code&gt;1&lt;/code&gt;&#38;#39;s and &lt;code&gt;0&lt;/code&gt;&#38;#39;s, you remember that you need a different last expression in the &lt;code&gt;map&lt;/code&gt; block:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@old&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;But then, you find out that &lt;code&gt;@new&lt;/code&gt; is the same as &lt;code&gt;@old&lt;/code&gt; because the &lt;code&gt;s///&lt;/code&gt; with the aliased &lt;code&gt;$_&lt;/code&gt; actually changes the original data. So, you expand the block a bit:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$s&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$s&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$s&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@old&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;That&#38;#39;s ugly. So, you upgrade to Perl 5.14 to get back to almost what you had before. Once you convince your entire company to upgrade, update all of your operating systems and packages, and reinstall all the modules, the &lt;code&gt;/r&lt;/code&gt; flag saves you a lot of hassle inside the block:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@new&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/rg&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@old&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This is useful with &lt;code&gt;printf&lt;/code&gt; too, where you might want to modify a string just for the output, but leaving the original alone:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;word&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;%s %s\n&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;substitute&#34;&gt;s/PATTERN/REPLACEMENT/rg&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;substitute&#34;&gt;s/PATTERN2/REPLACEMENT/rg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;With the &lt;code&gt;/r&lt;/code&gt; flag, it&#38;#39;s now convenient to have the &lt;code&gt;s///&lt;/code&gt; in the middle of larger expressions.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2011-12-13T00:00:00-05:00</updated><category term="Perl"/><author><name>brian d foy</name></author></entry><entry><title>Now I have an SQL machine gun</title><link href="http://perladvent.org/2011/2011-12-12.html"/><id>http://perladvent.org/2011/2011-12-12.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Where-do-you-keep-your-SQL-&#34;&gt;Where do you keep your SQL?&lt;/h2&gt;

&lt;p&gt;Do you use a database with Perl? I don&#38;#39;t mean one of those new-fangled No-SQL ones; I mean one of those SQL classics. You do? Where do you keep your SQL?&lt;/p&gt;

&lt;p&gt;You&#38;#39;ve got an ORM, check! You&#38;#39;ve got abstractions to hide your queries, check! But do you have any SQL lying around in files? Maybe your schema? Maybe you&#38;#39;ve got several different schemas? Different versions? Maybe ones for testing? Maybe for different database engines? (Thank you &lt;a href=&#34;https://metacpan.org/module/SQL::Translator&#34;&gt;SQL::Translator&lt;/a&gt;!)&lt;/p&gt;

&lt;h2 id=&#34;How-do-you-run-your-SQL-&#34;&gt;How do you run your SQL?&lt;/h2&gt;

&lt;p&gt;Do you use the command line client for each database? Do you remember the syntax for each one? If you run SQL from automated tests, do you always use the same type of database? Do you use the same connection parameters? Or do you mix it up?&lt;/p&gt;

&lt;p&gt;If you&#38;#39;re the type of person who like to keep things DRY (&#38;quot;don&#38;#39;t repeat yourself&#38;quot;), then doing things &lt;i&gt;one&lt;/i&gt; way for SQL code with command line tools and then &lt;i&gt;another&lt;/i&gt; way in your Perl code probably drives you crazy.&lt;/p&gt;

&lt;h2 id=&#34;Why-not-just-use-DBI-instead-&#34;&gt;Why not just use DBI, instead?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/DBIx::RunSQL&#34;&gt;DBIx::RunSQL&lt;/a&gt; is your SQL machine gun. It takes an SQL file, chops it up into statements, and fires them at your database through good, old &lt;a href=&#34;https://metacpan.org/module/DBI&#34;&gt;DBI&lt;/a&gt;. You probably don&#38;#39;t want to do that for a database dump with a million INSERT statements, but for schemas, it&#38;#39;s &lt;b&gt;great&lt;/b&gt;!&lt;/p&gt;

&lt;p&gt;Here&#38;#39;s an example adapted from the synopsis to initialize a new database for testing. First, we drop our schema into &lt;i&gt;sql/create.sql&lt;/i&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synStatement&#34;&gt;CREATE&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; chapters (&lt;br /&gt;&#38;nbsp;&#38;nbsp;chapterid int(&lt;span class=&#34;synConstant&#34;&gt;10&lt;/span&gt;) &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;longtitle &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;80&lt;/span&gt;) &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;&#39;&#39;&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;shorttitle &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;40&lt;/span&gt;) &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;CREATE&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; deletes (&lt;br /&gt;&#38;nbsp;&#38;nbsp;deleteid &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;255&lt;/span&gt;) &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;&#39;&#39;&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;changed &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;10&lt;/span&gt;) &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;changedby &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;10&lt;/span&gt;) &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;PRIMARY KEY (deleteid)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;CREATE&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; distmtimes (&lt;br /&gt;&#38;nbsp;&#38;nbsp;dist &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;128&lt;/span&gt;) &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;&#39;&#39;&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;distmtime &lt;span class=&#34;synType&#34;&gt;char&lt;/span&gt;(&lt;span class=&#34;synConstant&#34;&gt;10&lt;/span&gt;) &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;distmdatetime datetime &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synConstant&#34;&gt;&#39;0000-00-00 00:00:00&#39;&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;indexing_at datetime &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;indexed_at datetime &lt;span class=&#34;synSpecial&#34;&gt;DEFAULT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;PRIMARY KEY (dist)&lt;br /&gt;);&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...and probably in reality we&#38;#39;ve got quite a few more tables to create. The we read in the SQL and fire it off:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBIx::RunSQL&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DBIx::RunSQL&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;dsn&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;dbi:SQLite:dbname=:memory:&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;sql&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;sql/create.sql&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# Now use $dbh as your database handle for testing&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;You can also reuse an existing DBI handle:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;connect_to_db&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;list_of_schema_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;DBIx::RunSQL&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;run_sql_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;dbh&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dbh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;sql&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;There you go. Now you can keep your SQL files, but execute them from inside your Perl code with the connection you already have. Ho-Ho-Ho!&lt;/p&gt;

&lt;h2 id=&#34;SEE-ALSO&#34;&gt;SEE ALSO&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/DBIx::RunSQL&#34;&gt;DBIx::RunSQL&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/SQL::Translator&#34;&gt;SQL::Translator&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-12T00:00:00-05:00</updated><category term="Perl"/><author><name>David Golden</name></author></entry><entry><title>Mojolicious as a client</title><link href="http://perladvent.org/2011/2011-12-11.html"/><id>http://perladvent.org/2011/2011-12-11.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Mojolicious&#34;&gt;Mojolicious&lt;/a&gt; isn&#38;rsquo;t just a framework for websites. It&#38;rsquo;s also a web client. Until &lt;a href=&#34;http://www.mojolicio.us&#34;&gt;Mojolicious&lt;/a&gt;, the only reasonable general-purpose web client for Perl was &lt;a href=&#34;https://metacpan.org/module/LWP::UserAgent&#34;&gt;LWP::UserAgent&lt;/a&gt; (Library-WWW for Perl). That library has been around for a long time, has many things built on top of it, and is actively maintained.&lt;/p&gt;

&lt;p&gt;I like writing web clients, and I&#38;rsquo;ve used LWP::UserAgent for years. I&#38;rsquo;m used to it, know its insides, and can get things done. I didn&#38;rsquo;t have any reason to switch until I saw &lt;a href=&#34;http://www.slideshare.net/marcusramberg/mojolicious-a-new-hope&#34;&gt;Marcus Ramberg&#38;rsquo;s presentation on Mojolicious&lt;/a&gt; at the &lt;a href=&#34;http://conferences.yapceurope.org/npw2011/&#34;&gt;Nordic Perl Workship&lt;/a&gt;. After playing with it a bit, I think I like it much more. There&#38;#39;s a richer interface, more functionality, and I think even the internals are nicer.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Mojolicious&#34;&gt;Mojolicious&lt;/a&gt; is another framework from Sebastian Riedel, whom you may remember from other frameworks. Sebastian wanted to create a self-contained web thingy that would handle everything you might need for the &#38;quot;HTML5 web&#38;quot;. It wasn&#38;rsquo;t just going to fetch resources for you, it was going to parse it and let you walk it too. And, almost all of this was going to happen out of the box without add-ons. I think he, and the rest of the &lt;a href=&#34;https://metacpan.org/module/Mojolicious&#34;&gt;Mojolicious&lt;/a&gt; community, got it mostly right.&lt;/p&gt;

&lt;p&gt;A simple program to print a webpage looks similar to what I would do with LWP::UserAgent:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;5.010&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;http://www.perladvent.org/&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It gets more interesting when I want to do something with the response. I can immediately access the HTML DOM, for instance:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;5.010&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;http://www.perladvent.org/&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dom&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;I can also do more fancy processing. I can extract the titles of articles in the feed for &lt;a href=&#34;http://blogs.perl.org&#34;&gt;blogs.perl.org&lt;/a&gt;. The &lt;code&gt;each&lt;/code&gt; method:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;5.010&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;http://blogs.perl.org/atom.xml&#39;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dom&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;entry &#38;gt; title&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;state&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$n&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$n&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;: &#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;I might even do parallel requests with &lt;a href=&#34;https://metacpan.org/module/Mojo::IOLoop&#34;&gt;Mojo::IOLoop&lt;/a&gt;. Since I&#38;rsquo;m fetching pages from &lt;a href=&#34;https://www.metacpan.org&#34;&gt;MetaCPAN&lt;/a&gt;, I needed to install &lt;a href=&#34;https://metacpan.org/module/IO::Socket::SSL&#34;&gt;IO::Socket::SSL&lt;/a&gt;. This bit of code grabs the latest version number for each module (there&#38;rsquo;s a better way to do this, though):&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;br /&gt;23:&#38;nbsp;&lt;br /&gt;24:&#38;nbsp;&lt;br /&gt;25:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;5.010&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::IOLoop&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$delay&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::IOLoop&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;delay&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@modules&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(Mojolicious Set::CrossProduct DBD::SQLite)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$module&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@modules&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$url&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;https://www.metacpan.org/module/$module&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$delay&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;begin&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$url&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tx&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$version&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tx&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;dom&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;div.search-bar &#38;gt; div &#38;gt; ul &#38;gt; li&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;];&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$module: &#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$version&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;m|Module version: (\S+)&#38;lt;/li&#38;gt;|&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$delay&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$delay&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If the response isn&#38;rsquo;t HTML, but is JSON, like you would expect from AJAXy-like web thingys, you can easily handle that too. I get immediate access to the data without loading additional modules:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;5.010&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Mojo::UserAgent&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ua&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;http://example.com/data.json&#39;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;cat&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The &lt;a href=&#34;https://metacpan.org/module/ojo&#34;&gt;ojo&lt;/a&gt; module lets you do these from the command line, too. It provides shortcuts. Notice that the call to &lt;code&gt;res&lt;/code&gt; has disappeared because the &lt;code&gt;g&lt;/code&gt; shortcut returns that for you:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;% perl -Mojo -E &#38;#39;say g(&#38;quot;http://www.perladvent.org&#38;quot;)-&#38;gt;body&#38;#39;&lt;br /&gt;&lt;br /&gt;% perl -Mojo -E &#38;quot;g(&#38;#39;http://blogs.perl.org/atom.xml&#38;#39;)-&#38;gt;dom(&#38;#39;entry &#38;gt; title&#38;#39;)&lt;br /&gt;&#38;nbsp;&#38;nbsp;-&#38;gt;each(sub{state \$n=0;say ++\$n,&#38;#39;: &#38;#39;,\$_-&#38;gt;text})&#38;quot;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The &lt;a href=&#34;https://metacpan.org/module/Mojo::UserAgent&#34;&gt;Mojo::UserAgent&lt;/a&gt; can do much more powerful things, but this should be enough to whet your appetite.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Mojo::UserAgent&#34;&gt;Mojo::UserAgent&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Mojolicious&#34;&gt;Mojolicious&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/ojo&#34;&gt;ojo&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-11T00:00:00-05:00</updated><category term="Perl"/><author><name>brian d foy</name></author></entry><entry><title>A Big List of Stuff You Want</title><link href="http://perladvent.org/2011/2011-12-10.html"/><id>http://perladvent.org/2011/2011-12-10.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Perl-Is-Not-Enough&#34;&gt;Perl Is Not Enough&lt;/h2&gt;

&lt;p&gt;Perl has lots of useful built-in functions. Everybody loves &lt;code&gt;grep&lt;/code&gt;, right?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@coal_kids&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;grep&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;is_naughty&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@children&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Maybe we only want the first element, though. There&#38;#39;s more than one way to do it &#38;ndash; here are two:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;comment&#34;&gt;# This works just fine, but you might be waiting a while, since it&#39;s going to&lt;br /&gt;# evaluate the block for every item in the list.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$first_coal_goes_to&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;grep&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;is_naughty&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@children&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# This is a lot more efficient to run, but not to write.  Worse, it&#39;s not&lt;br /&gt;# anywhere near as efficient to skim.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$first_coal_goes_to&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;@children&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;next&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;is_naughty&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$first_coal_goes_to&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Fortunately, we&#38;#39;ve got &lt;a href=&#34;https://metacpan.org/module/List::Util&#34;&gt;List::Util&lt;/a&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;List::Util&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(first)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$first_coal_goes_to&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;first&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;is_naughty&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@children&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It&#38;#39;s easy to read, easy to write, and works efficiently, stopping at the first hit.&lt;/p&gt;

&lt;p&gt;List::Util has a bunch of useful stuff like this. It has routines for summing up numbers, or finding maxima and minima. It&#38;#39;s got a &lt;code&gt;shuffle&lt;/code&gt; routine for randomizing lists, which you should use. I can&#38;#39;t tell you how many &lt;i&gt;horrible&lt;/i&gt; reimplementations of List::Util&#38;#39;s shuffle I&#38;#39;ve deleted over the years.&lt;/p&gt;

&lt;p&gt;Even more importantly, though, it provides a &lt;code&gt;reduce&lt;/code&gt; method. &lt;code&gt;reduce&lt;/code&gt; is a really common higher-order function, often called &lt;code&gt;fold&lt;/code&gt;. You can use it to build lots of other really useful behavior. For example, we might use it to reimplement &lt;code&gt;sum&lt;/code&gt;, since the one that comes with List::Util stinks&#38;sup1;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reduce&lt;/code&gt; is called with a function (usually written as a block) and a list of inputs. If there&#38;#39;s only one item in the list, it returns that. Otherwise, it calls the function with the first two items and makes the result the new head of the list. Confused?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@numbers&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;get_numbers&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sum&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;reduce&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$a&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$b&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@numbers&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If &lt;code&gt;@numbers&lt;/code&gt; is empty, we return 0. If &lt;code&gt;@numbers&lt;/code&gt; contains (1, 2, 3), this is what happens:&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;We have more than one item in the list! Our input is (0, 1, 2, 3)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shift off 0 and 1, and unshift the result back onto the input.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now our input is (1, 2, 3)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shift off 1 and 2, and unshift the result back onto the input.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now our input is (3, 3)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shift off 3 and 3, and unshift the result back onto the input.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now our input is (6)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There&#38;#39;s only one input! Return it!&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;i&gt;Lots&lt;/i&gt; of stuff can get implemented in terms of &lt;code&gt;reduce&lt;/code&gt;. Knowing how (and when) to use it is really useful. In fact, the List::Util documentation points out how several of its functions could have been written as folding constructs instead.&lt;/p&gt;

&lt;h2 id=&#34;List::Util-is-Not-Enough&#34;&gt;List::Util is Not Enough&lt;/h2&gt;

&lt;p&gt;List::Util&#38;#39;s documentation also lists a few things that people have proposed for inclusion over the years, like &lt;code&gt;any&lt;/code&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;any&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;amp;&#38;amp;&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The docs say that &lt;code&gt;any&lt;/code&gt; has been omitted because it&#38;#39;s so easy to write inline (especially if you have &lt;code&gt;first&lt;/code&gt;). Still, why not make them available? &lt;a href=&#34;https://metacpan.org/module/List::MoreUtils&#34;&gt;List::MoreUtils&lt;/a&gt; does just that, providing all the routines List::Util declined to and &lt;i&gt;much&lt;/i&gt; more.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;comment&#34;&gt;# Note that you couldn&#39;t do this as easily with first, because it would&lt;br /&gt;# return undef on both success and failure.  Also note that List::MoreUtil&#39;s&lt;br /&gt;# &#38;quot;any&#38;quot; takes a block, not just a list.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;any&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;core&#34;&gt;defined&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@input_values&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# Get every element until the block returns true.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@first_half_alphabet&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;before&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;last_name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/^N/i&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@children&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;List::MoreUtils also helps get rid of many occurances of &lt;code&gt;%seen&lt;/code&gt;, one of my least favorite often-seen variables:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;comment&#34;&gt;# Don&#39;t write:&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@unique_guesses&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%seen&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{;&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@guesses&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%seen&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# Write:&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@unique_guesses&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;uniq&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@guesses&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;And it provides the terribly-named &lt;code&gt;natatime&lt;/code&gt; for processing &lt;i&gt;n&lt;/i&gt; elements at a time:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;natatime&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@pairs&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$k&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$v&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$key has value $v&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;Theres-a-Lot-More&#34;&gt;There&#38;#39;s a Lot More&lt;/h2&gt;

&lt;p&gt;I&#38;#39;ve only given a very thin gloss over List::Util, and barely scratched the surface of List::MoreUtils. The point is that these two libraries are useful all the time. If you haven&#38;#39;t used them yet, it&#38;#39;s almost certain that you could&#38;#39;ve saved time by using them a few times. Learn what&#38;#39;s in them, and consider them a tool you can reach for without thinking about it.&lt;/p&gt;

&lt;p&gt;In fact, to help you not have to think about it, don&#38;#39;t use either of them! Instead, use &lt;a href=&#34;https://metacpan.org/module/List::AllUtils&#34;&gt;List::AllUtils&lt;/a&gt;, which provides all the routines of the other two, combined into one library so you don&#38;#39;t have to try to remember whether &lt;code&gt;minmax&lt;/code&gt; is from Util or MoreUtils&#38;sup2;.&lt;/p&gt;

&lt;h2 id=&#34;Footnotes&#34;&gt;Footnotes&lt;/h2&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;List::Util&#38;#39;s sum returns undef, instead of 0, for an empty input list.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; are from Util, but &lt;code&gt;minmax&lt;/code&gt; is from MoreUtils&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/List::Util&#34;&gt;List::Util&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/List::MoreUtils&#34;&gt;List::MoreUtils&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/List::AllUtils&#34;&gt;List::AllUtils&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-10T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Taming Search with Data::SearchEngine</title><link href="http://perladvent.org/2011/2011-12-09.html"/><id>http://perladvent.org/2011/2011-12-09.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Sooner or later it&#38;#39;s going to happen: Someone will request a feature of your application&#38;#39;s search code. It might be gentle at first. A casual remark about speed, functionality or scalability will meander into your bug tracker, standup meeting or planning session. At first you will nod and file it away, knowing that it takes a few requests for something to really stick. Pretty soon a second, perhaps unrelated, request will arrive. Before you know it you&#38;#39;ll be surrounded by reminders, almost &lt;a href=&#34;http://en.wikipedia.org/wiki/Tribble&#34;&gt;Tribble-like&lt;/a&gt;, of a sobering fact:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM table WHERE description LIKE &#38;quot;whatever%&#38;quot;&lt;/code&gt; isn&#38;#39;t going to cut it anymore.&lt;/p&gt;

&lt;h3 id=&#34;Investigating-Your-Options&#34;&gt;Investigating Your Options&lt;/h3&gt;

&lt;p&gt;There are &lt;b&gt;lots&lt;/b&gt; of ways to add search to your application. The details of which largely depend on the type of data you are searching. You are on your own for evaluating and testing search-engines. There are plenty of resources for that task.&lt;/p&gt;

&lt;p&gt;Instead, lets focus on what to do to minimize the impact to your application when adopting or changing search engines.&lt;/p&gt;

&lt;h3 id=&#34;The-Problem-with-Search&#34;&gt;The Problem with Search&lt;/h3&gt;

&lt;p&gt;Every search library has a different interface. Assuming you are using something similar to &lt;a href=&#34;http://en.wikipedia.org/wiki/Model&#38;ndash;view&#38;ndash;controller&#34;&gt;MVC&lt;/a&gt;, you&#38;#39;ll have code in each layer that deals with the implementation-specific functionality. Your controller will have to parse requests and build queries to send to the model, and the view will need to iterate over and display the results. The model will bear the brunt of the changes, but that&#38;#39;s what models are for.&lt;/p&gt;

&lt;p&gt;Needing to rewrite our controller and view every time we adjust our search or &#38;ndash; worse yet &#38;ndash; each time we evaluate a new search product is a real pain. I bet we can fix this if we just add another layer of abstraction!&lt;/p&gt;

&lt;h3 id=&#34;Enter-Data::SearchEngine&#34;&gt;Enter Data::SearchEngine&lt;/h3&gt;

&lt;p&gt;Data::SearchEngine is a toolbox that comes with everything you need to wrap a pretty API around your search implementation. It even has two wrappers already written: one for &lt;a href=&#34;http://lucene.apache.org/solr/&#34;&gt;Solr&lt;/a&gt; and one for &lt;a href=&#34;http://www.elasticsearch.org/&#34;&gt;ElasticSearch&lt;/a&gt;. Before we talk about those let&#38;#39;s take a moment to wrap up your average SQL-based search with these tools so you can see how they work.&lt;/p&gt;

&lt;h3 id=&#34;Step-1:-Subclass-&#34;&gt;Step 1: Subclass!&lt;/h3&gt;

&lt;p&gt;First, you&#38;#39;ll want to create a Data::SearchEngine::MySearch that wraps your implementation:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::SearchEngine::MySearch&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Moose&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Data::SearchEngine&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;search&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;We&#38;#39;re consuming a &lt;a href=&#34;https://metacpan.org/module/Moose::Cookbook::Roles::Recipe1&#34;&gt;Moose roles&lt;/a&gt; called &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine&#34;&gt;Data::SearchEngine&lt;/a&gt; that requires the implementation of a method called &lt;code&gt;search&lt;/code&gt;. Let&#38;#39;s imagine that your search code just searches a databases using &lt;code&gt;LIKE&lt;/code&gt;. I&#38;#39;m sure you can imagine a bit of code that executes that query and gets back a resultset, right? Great! Let&#38;#39;s move on to the next bit then.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; That role also requires that you implement &lt;code&gt;find_by_id&lt;/code&gt;. You can just make an empty sub to satisfy it for now.&lt;/p&gt;

&lt;h3 id=&#34;Step-2:-Getting-the-Query&#34;&gt;Step 2: Getting the Query&lt;/h3&gt;

&lt;p&gt;The query is the request that the user has given us to find something. This is where the rubber really meets the road, as we need to create a query format that any search engine can use. We won&#38;#39;t try to abstract the syntax, but we can provide a container:&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Query&#34;&gt;Data::SearchEngine::Query&lt;/a&gt; gives us a simple Query object:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::SearchEngine::Query&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;count&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# the number of results we&#39;d like&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;page&lt;/span&gt;  &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# the page we are on&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;elephants&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# the query we&#39;re searching for&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$se&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::SearchEngine::MySearch&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$results&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$se&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Easy, eh? Your search backend may need more information or have a more complex query format, but that&#38;#39;s ok. Data::SearchEngine::Query has a permissive &lt;code&gt;query&lt;/code&gt; attribute plus hooks for things like filters.&lt;/p&gt;

&lt;h3 id=&#34;Step-3:-Results-&#34;&gt;Step 3: Results!&lt;/h3&gt;

&lt;p&gt;That last code example showed getting results back. How does that work? Let&#38;#39;s write it! Start with our &lt;code&gt;MySearch&lt;/code&gt; example earlier, but put some meat on it&#38;#39;s bones:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;br /&gt;23:&#38;nbsp;&lt;br /&gt;24:&#38;nbsp;&lt;br /&gt;25:&#38;nbsp;&lt;br /&gt;26:&#38;nbsp;&lt;br /&gt;27:&#38;nbsp;&lt;br /&gt;28:&#38;nbsp;&lt;br /&gt;29:&#38;nbsp;&lt;br /&gt;30:&#38;nbsp;&lt;br /&gt;31:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;search&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # ... your internal search junk, run some SQL maybe?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::SearchEngine::Results&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;pager&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::Paginator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;current_page&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;entries_per_page&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;total_entries&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# results from your query!&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # Iterate over your resultset here.&lt;br /&gt;&lt;/span&gt;  &lt;span class=&#34;keyword&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$hit&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;@hits&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;Data::SearchEngine::Item&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$hit&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# The unique id for this item&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;          # Put any data you want to use in your result listing into&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;# this values hash.&lt;br /&gt;&lt;/span&gt;          &lt;span class=&#34;word&#34;&gt;values&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$hit&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$hit&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;description&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$hit&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;score&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;));&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # Return the result&lt;br /&gt;&lt;/span&gt;  &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;That bit of code is pretty simple. We run our query and then store each row that is returned for that page in a &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Results&#34;&gt;Data::SearchEngine::Results&lt;/a&gt; object. Now that we have our results we can show them to the user.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Data::SearchEngine uses a special paginator class called &lt;a href=&#34;https://metacpan.org/module/Data::Paginator&#34;&gt;Data::Paginator&lt;/a&gt; that has many of the features of &lt;a href=&#34;https://metacpan.org/module/Data::Page&#34;&gt;Data::Page&lt;/a&gt; and &lt;a href=&#34;https://metacpan.org/module/Data::Pageset&#34;&gt;Data::Pageset&lt;/a&gt;. Since all of Data::SearchEngine is serializable there needed to be an easily serializable, Moose-based pagination module. Hence Data::Paginator!&lt;/p&gt;

&lt;h3 id=&#34;Step-4:-Show-Our-Answers&#34;&gt;Step 4: Show Our Answers&lt;/h3&gt;

&lt;p&gt;The aforementioned Results object has an attribute &lt;code&gt;items&lt;/code&gt;. This is an array of &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Item&#34;&gt;Data::SearchEngine::Item&lt;/a&gt; objects. Displaying our results is as simple as iterating over this array. We&#38;#39;ll write this in Perl, but it&#38;#39;s easy to translate into your favorite templating module.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$item&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;cast&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;items&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$item&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$item&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get_value&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;\n&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;That&#38;#39;s it! You&#38;#39;ll use &lt;code&gt;get_value&lt;/code&gt; to retrieve any fields other than &lt;code&gt;id&lt;/code&gt; from the item.&lt;/p&gt;

&lt;h3 id=&#34;Done-So-Now-What-&#34;&gt;Done, So Now What?&lt;/h3&gt;

&lt;p&gt;You&#38;#39;ve now successfully wrapped your internal search code with a powerful abstraction. You could now easily experiment with &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::ElasticSearch&#34;&gt;ElasticSearch&lt;/a&gt; or &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Solr&#34;&gt;Solr&lt;/a&gt;, the two search products for which there are existing Data::SearchEngine backends. Or you could take what you&#38;#39;ve just learned and create a new backend for a different search product.&lt;/p&gt;

&lt;h3 id=&#34;Some-Other-Noteworthy-Features&#34;&gt;Some Other Noteworthy Features&lt;/h3&gt;

&lt;p&gt;The Query object has lots of convenience methods for filtering (limiting your results via a filter such as &#38;quot;price &#38;gt; 20&#38;quot;) and faceting (counting the number of items with different attributes so you can filter them). It will also generate a unique digest based on it&#38;#39;s attributes so that you can cache results.&lt;/p&gt;

&lt;p&gt;The Results object can be subclassed if your implementation needs some new features. There are existing roles for &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Results::Faceted&#34;&gt;Faceting&lt;/a&gt; and &lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine::Results::Spellcheck&#34;&gt;Spellchecking&lt;/a&gt;. Just have your &lt;code&gt;search&lt;/code&gt; method return the subclass.&lt;/p&gt;

&lt;p&gt;Results, Query and Item objects are all serializable using &lt;a href=&#34;https://metacpan.org/module/MooseX::Storage&#34;&gt;MooseX::Storage&lt;/a&gt; via &lt;a href=&#34;https://metacpan.org/module/MooseX::Storage::Deferred&#34;&gt;Deferred&lt;/a&gt;. This is provided to make caching easy.&lt;/p&gt;

&lt;p&gt;Finally, keep in mind that Query is just a guide. Your implementation may require much more complex syntax and Data::SearchEngine tries to stay out of the way. For example the ElasticSearch query DSL uses hashrefs, not strings:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;comment&#34;&gt;# A real example using ElasticSearch&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$query&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::SearchEngine::Query&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;count&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;query_string&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;query&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;foobar&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;order&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;date_crated&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;desc&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h3 id=&#34;Conclusion&#34;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;You might not change search backends every week, but taking a bit of time to wrap your custom implementation in something featureful can save you a lot of trouble down the road. It also provides you with some great features as a result!&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Data::SearchEngine&#34;&gt;Data::SearchEngine&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-09T00:00:00-05:00</updated><category term="Perl"/><author><name>Cory G Watson</name></author></entry><entry><title>All the perls are all lined up</title><link href="http://perladvent.org/2011/2011-12-08.html"/><id>http://perladvent.org/2011/2011-12-08.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;I-can-test-just-what-I-want&#34;&gt;I can test just what I want&lt;/h2&gt;

&lt;p&gt;I like to pretend that I can just target the latest stable release of &lt;code&gt;perl&lt;/code&gt; and that&#38;#39;s that. It&#38;#39;s what I run on my computers, after all. Unfortunately, at work, we have two different deployed versions, so I need to support those, too. But that&#38;#39;s only two versions, right?&lt;/p&gt;

&lt;p&gt;Well, not really. The problem is that I release as much of my code as seems reasonable to the CPAN, and that means I get bug reports from lots of different versions. My least favorite five words? &#38;quot;It doesn&#38;#39;t work on 5.8.1.&#38;quot; (You may be thinking, &#38;quot;Why 5.8.1 and not 5.6.1?&#38;quot; Well, because if it&#38;#39;s 5.6.1, I&#38;#39;ll usually send condolences instead of bugfixes.)&lt;/p&gt;

&lt;p&gt;So, what do I do when I get that bug report? If it looks like a plausible bug (and not an obvious user error), my next action is almost always to see whether I can reproduce it. If the bug really is just in 5.8.1, and I can&#38;#39;t reproduce it in my 5.14.1, or the 5.8.8 readily available on some other box sitting around, I&#38;#39;ll have to buck up and install 5.8.1.&lt;/p&gt;

&lt;p&gt;The last thing I want, though, is to end up with a zillion &lt;code&gt;perl5.x.y&lt;/code&gt; binaries in my path, each partially sharing its library paths, different installs of this or that being alternately shared or not shared between interpreters. It&#38;#39;s pretty easy to get that with the right arguments to the &lt;i&gt;Configure&lt;/i&gt; program that builds &lt;code&gt;perl&lt;/code&gt; &#38;ndash; oh, and right. I&#38;#39;d have to &lt;i&gt;run&lt;/i&gt; the &lt;i&gt;Configure&lt;/i&gt; program, build, test, install, and so on. Some versions would need patches to build on my OS X box. What a drag.&lt;/p&gt;

&lt;p&gt;Fortunately, I am free from having to suffer through any of this, because I can use &lt;code&gt;&lt;a href=&#34;http://perlbrew.pl&#34;&gt;perlbrew&lt;/a&gt;&lt;/code&gt; from &lt;a href=&#34;https://metacpan.org/author/GUGOD&#34;&gt;gugod&lt;/a&gt;. It manages a bunch of parallel Perl installs. If you&#38;#39;re familiar with Ruby&#38;#39;s &lt;code&gt;&lt;a href=&#34;http://beginrescueend.com/&#34;&gt;rvm&lt;/a&gt;&lt;/code&gt;, then you already know what &lt;code&gt;perlbrew&lt;/code&gt; is, more or less.&lt;/p&gt;

&lt;p&gt;If you don&#38;#39;t, here&#38;#39;s how you get started &#38;ndash; we&#38;#39;ll talk about how you use it in a bit, if you&#38;#39;re not sure you want to install it, but you can trust me: you do.&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;install App::perlbrew with your favorite CPAN client (cpan, cpanp, cpanm, ppm, whatever)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run &lt;code&gt;perlbrew init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will print out a big friendly message saying what it did, and it will include one key line, something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  source ~/perl5/perlbrew/etc/bashrc&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add that &lt;code&gt;source&lt;/code&gt; line to your &lt;i&gt;~/.bashrc&lt;/i&gt; or &lt;i&gt;.zshrc&lt;/i&gt; or whatever&lt;/p&gt;

&lt;p&gt;Now when you open a new shell, it will look for stuff installed into &lt;code&gt;perlbrew&lt;/code&gt;-managed Perl environment instead of the global system environment first.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run &lt;code&gt;perlbrew install perl-5.14.2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now &lt;code&gt;perlbrew&lt;/code&gt; will start doing the first hunk of boring that you&#38;#39;re getting to avoid: configuring, building, testing, and installing &lt;code&gt;perl&lt;/code&gt; v5.14.2. If it knows that it will have to patch the source to compile (by using &lt;a href=&#34;https://metacpan.org/release/Devel-PatchPerl&#34;&gt;Devel-PatchPerl&lt;/a&gt;, it will. It will give the &lt;code&gt;perl&lt;/code&gt; its &lt;i&gt;entirely self-contained&lt;/i&gt; set of &lt;code&gt;@INC&lt;/code&gt; libraries, install paths, and so on. &lt;i&gt;No libraries&lt;/i&gt; are getting shared with your system &lt;code&gt;perl&lt;/code&gt;, and it won&#38;#39;t leak the other way, either.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;do something fun while it compiles&lt;/p&gt;

&lt;p&gt;Or, if you think it&#38;#39;s fun, you can tail the log file &#38;ndash; &lt;code&gt;perlbrew&lt;/code&gt; will have told you its path &#38;ndash; to see how the build is going.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;open a new shell (or run that &lt;code&gt;source&lt;/code&gt; line in this one)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run &lt;code&gt;perlbrew switch perl-5.14.2&lt;/code&gt; to make it your active perl&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run &lt;code&gt;perl -v&lt;/code&gt; and rejoice&lt;/p&gt;

&lt;p&gt;(Remember that if you just sourced that file in an existing shell like &lt;code&gt;zsh&lt;/code&gt;, you might need to run &lt;code&gt;rehash&lt;/code&gt;!)&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, great, you have &lt;code&gt;perl&lt;/code&gt;. So what?&lt;/p&gt;

&lt;p&gt;Well, go ahead and repeat steps 4 through 8, picking another version. You&#38;#39;ll end up with several installed Perl environments, each with its own libraries. Not only that, but you&#38;#39;ll have &lt;code&gt;cpanm&lt;/code&gt; preinstalled. So, someone told you that your Awesome::Library is busted on 5.8.9?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ perlbrew switch perl-5.8.9&lt;br /&gt;$ cpanm -v Awesome::Library&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...and you&#38;#39;ll see the build process occur right there in your own 5.8.9 install.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;One warning&lt;/i&gt;: trying this out, you may find some versions won&#38;#39;t compile for you. Not every version still compiles cleanly with modern libraries and tools. PatchPerl, included with &lt;code&gt;perlbrew&lt;/code&gt; should take care of this, but it doesn&#38;#39;t handle everything. For example, on Mac OS X 10.7, probably only 5.14.2 will compile. These tend to get addressed eventually, but it won&#38;#39;t ever be perfect.&lt;/p&gt;

&lt;p&gt;You can install more than one copy of any given perl, too. Maybe you want to have different sets of libraries installed &#38;ndash; although really you could just use &lt;a href=&#34;http://perladvent.org/2011/2011-12-01.html&#34;&gt;local::lib&lt;/a&gt; for that. Maybe, though, you want the same version with different options. These are all useful:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  perlbrew install perl-5.14.2 -Dusethreads --as threaded-5.14.2

  perlbrew install perl-5.14.2 -DDEBUGGING --as debug-5.14.2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...and you probably want to know that &lt;code&gt;-j&lt;/code&gt; works to make and test in parallel:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  perlbrew install -j 5 perl-5.14.2&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;Take-your-perl-and-roll-it-back&#34;&gt;Take your perl and roll it back&lt;/h2&gt;

&lt;p&gt;If you really need to make &lt;code&gt;which perl&lt;/code&gt; start returning your old global perl or its installed programs &#38;ndash; which should probably never happen &#38;ndash; you can get &lt;code&gt;perlbrew&lt;/code&gt; out of the way with &lt;code&gt;perlbrew off&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, you probably don&#38;#39;t need to do this. If you&#38;#39;ve got &lt;code&gt;perl&lt;/code&gt; installed for your system at &lt;i&gt;/usr/bin/perl&lt;/i&gt; you can just put that in the shebang lines as needed. You can run &lt;code&gt;/usr/bin/perl $(which cpanm)&lt;/code&gt; when you need to install things to the global install, and so on. Almost certainly, though, you&#38;#39;ll quickly find that you don&#38;#39;t need to muck with it nearly at all.&lt;/p&gt;

&lt;p&gt;More likely, you&#38;#39;ll start finding that you&#38;#39;ve got personal scripts that are using the system perl in their shebang, but your library updates are now going to perlbrew. That&#38;#39;s easy to fix, and you do some nice simple things this way. For example, you can write this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;comment&#34;&gt;#!/home/rjbs/perl5/perlbrew/perls/perl-5.14.2/bin/perl&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;version&#34;&gt;5.14.1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;local::lib&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;/home/rjbs/.perlbrew/lib/safe&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;First of all, you&#38;#39;ve spelled out exactly what version of &lt;code&gt;perl&lt;/code&gt; to use, and that won&#38;#39;t go away when you install a new version -- it will stay there, working correctly, until you get everything working on 5.16 and (maybe) decide to delete your &lt;code&gt;perl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Secondly, you&#38;#39;ve decided to use a local::lib to keep the safe versions of all the libraries you&#38;#39;re going to use. Why is it under &lt;i&gt;~/.perlbrew&lt;/i&gt;? Because &lt;code&gt;perlbrew&lt;/code&gt; can manage your local::lib compartments, too:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ perlbrew switch perl-5.14.2&lt;br /&gt;$ perlbrew lib create safe&lt;br /&gt;$ perlbrew switch perl-5.14.2@safe&lt;br /&gt;$ cpanm install Something::Cool&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;In other words, we:&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;pick the perl for we want a local::lib&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a local::lib compartment called &#38;quot;safe&#38;quot; for that perl&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;switch to using it&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;install Something::Cool into it&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are some limitations, here. We can only have one active compartment at a time and we can&#38;#39;t re-use a compartment across two versions (even if we think it will be safe). Still, those are unlikely cases, and the base case is very, very useful.&lt;/p&gt;

&lt;h2 id=&#34;Doesnt-it-make-your-life-better-&#34;&gt;Doesn&#38;#39;t it make your life better?&lt;/h2&gt;

&lt;p&gt;It&#38;#39;s hard to explain how much simpler &lt;code&gt;perlbrew&lt;/code&gt; can make testing of Perl code. It&#38;#39;s not just testing, either. Obviously, this makes it easier to upgrade your code to a new version without having to go whole hog or have multiple versions installed in a single &lt;i&gt;bin&lt;/i&gt; dir. It lets you keep your one stupid-but-vital ancient tool working on 5.6 while the rest of your work is getting done on 5.14.&lt;/p&gt;

&lt;p&gt;Finally, even if you only ever use it for one &lt;code&gt;perl&lt;/code&gt;, it takes away a bunch of the headache of installing &lt;code&gt;perl&lt;/code&gt; and later libraries by doing all the configuration for you and putting everything into directories into which you can write, without &lt;code&gt;sudo&lt;/code&gt; or local::lib.&lt;/p&gt;

&lt;p&gt;You will not regret using &lt;code&gt;perlbrew&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::perlbrew&#34;&gt;App::perlbrew&lt;/a&gt; on the CPAN&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the &lt;a href=&#34;http://www.perlbrew.pl/&#34;&gt;perlbrew home page&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-08T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Unwrapping the Package(::Stash)</title><link href="http://perladvent.org/2011/2011-12-07.html"/><id>http://perladvent.org/2011/2011-12-07.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;A symbol table in perl (also known as a &lt;i&gt;stash&lt;/i&gt;, short for &#38;quot;symbol table hash&#38;quot;) is the place where perl stores variables and functions associated with a package. &lt;code&gt;our $Foo = &#38;quot;a&#38;quot;&lt;/code&gt;, &lt;code&gt;sub foo { }&lt;/code&gt;, and &lt;code&gt;@Child::ISA = (&#38;#39;Parent&#38;#39;)&lt;/code&gt; are all examples of storing values into package variables: the first two into whatever the current package happens to be and the third into a different package (&#38;#39;Child&#38;#39; in this case).&lt;/p&gt;

&lt;p&gt;When the package whose symbol table we are manipulating is known at compile time, these operations are easy and straightforward. Unfortunately, this isn&#38;#39;t always possible. Take modules which export functions for instance: the package that is requesting functions to be imported isn&#38;#39;t known when the exporting package is compiled, and it&#38;#39;s not even likely that there will be only one. Consider a typical &lt;code&gt;import&lt;/code&gt; function for a simple module which exports a few functions (ignoring for now the fact that something this simple should likely just use &lt;a href=&#34;https://metacpan.org/module/Exporter&#34;&gt;Exporter&lt;/a&gt; instead):&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%to_export&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;caller&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;no&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;strict&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;refs&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;cast&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;::foo&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;foo&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;cast&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;::bar&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;bar&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Symbolic references? Typeglobs&#38;sup1;? We &lt;i&gt;can&lt;/i&gt; rewrite this in a way that is &lt;a href=&#34;https://metacpan.org/module/strict&#34;&gt;strict&lt;/a&gt;-safe:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%to_export&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;%::&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$part&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;split&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/::/&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;caller&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\%&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$part&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;::&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;cast&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;*ANON&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;foo&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;cast&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;*ANON&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;bar&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;but... wow. Replacing symbolic references with even scarier typeglob magic isn&#38;#39;t really a win; there are reasons that most people just do &lt;code&gt;no strict &#38;#39;refs&#38;#39;&lt;/code&gt; and get on with it (not least because bugs in the perl core prevented this version from working before 5.14). It only gets worse if you want to do other things, like set a default base class if none exists (since superclasses are stored in the &lt;code&gt;@ISA&lt;/code&gt; package variable).&lt;/p&gt;

&lt;p&gt;As you may have guessed from that last example, these are issues that &lt;a href=&#34;https://metacpan.org/module/Moose&#34;&gt;Moose&lt;/a&gt; has had to deal with a lot of, in order for its introspection capabilities to be able to find existing methods and superclasses. Initially, this was contained in &lt;a href=&#34;https://metacpan.org/module/Class::MOP::Package&#34;&gt;Class::MOP::Package&lt;/a&gt;, but it was eventually split into its own distribution called &lt;a href=&#34;https://metacpan.org/module/Package::Stash&#34;&gt;Package::Stash&lt;/a&gt; so that people who don&#38;#39;t use Moose can avoid the hairy mess that is dynamic stash manipulation.&lt;/p&gt;

&lt;p&gt;Using Package::Stash, our &lt;code&gt;import&lt;/code&gt; method can be rewritten like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;core&#34;&gt;shift&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%to_export&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Package::Stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;caller&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_symbol&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;&#38;amp;foo&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$stash&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_symbol&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;&#38;amp;bar&#39;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;&#38;amp;bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$to_export&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This has the benefit of not requiring any thinking about (or even knowledge of) typeglobs and the storage representation of stashes&#38;sup2;, and makes these sorts of operations much more readable. For instance, doing something like setting a default version for a package can be done by &lt;code&gt;$stash-&#38;gt;add_symbol(&#38;#39;$VERSION&#38;#39; =&#38;gt; 0.01) unless $stash-&#38;gt;has_symbol(&#38;#39;$VERSION&#38;#39;)&lt;/code&gt;, which makes it very clear what is going on.&lt;/p&gt;

&lt;p&gt;So next time you think of reaching for &lt;code&gt;no strict &#38;#39;refs&#38;#39;&lt;/code&gt;, consider using Package::Stash instead. It&#38;#39;s much more readable and maintainable than direct stash access, it&#38;#39;s very well tested (being used by &lt;a href=&#34;https://metacpan.org/module/Moose&#34;&gt;Moose&lt;/a&gt;, &lt;a href=&#34;https://metacpan.org/module/namespace::clean&#34;&gt;namespace::clean&lt;/a&gt;, and &lt;a href=&#34;https://metacpan.org/module/Class::Load&#34;&gt;Class::Load&lt;/a&gt;, each of which do different bits of crazy symbol table manipulation, and each of which are very widely used), and it deals with a lot of weird bugs and edge cases in different versions of the core that you really don&#38;#39;t want to have to think about (trust me!).&lt;/p&gt;

&lt;h2 id=&#34;Footnotes&#34;&gt;Footnotes&lt;/h2&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;No, I&#38;#39;m not going to go into typeglobs here - for the purposes of this entry, you can think of them as &#38;quot;magic&#38;quot;, or look them up in &lt;code&gt;perldoc perldata&lt;/code&gt; if you&#38;#39;re especially curious.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For instance, does the output of &lt;code&gt;perl -e&#38;#39;package Foo; sub bar () { 1 }; use constant BAR =&#38;gt; 1; use Data::Dumper; warn Dumper(\%Foo::)&#38;#39;&lt;/code&gt; surprise you?&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Package::Stash&#34;&gt;Package::Stash&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-07T00:00:00-05:00</updated><category term="Perl"/><author><name>Jesse Luehrs</name></author></entry><entry><title>Make all the combinations</title><link href="http://perladvent.org/2011/2011-12-06.html"/><id>http://perladvent.org/2011/2011-12-06.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;You need to make combinations of things, but you don&#38;#39;t want to create them all at once, or you can&#38;#39;t create them all at once. You might only need one combination at a time.&lt;/p&gt;

&lt;p&gt;I had this problem when I was creating a test suite for a legacy application. I need to test all of the boundary conditions for several functions. The return values for the new subroutines I was writing needed to be the same as those from the original:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@tests&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # INPUT_ARGS&lt;br /&gt;&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( blood adanac 1 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( blood adanac 2 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( blood taylor 1 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( blood taylor 2 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( navel adanac 1 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # ... many more tuples&lt;br /&gt;&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@tests&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;Original::foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;New::foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;  &lt;span class=&#34;cast&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;Arguments [ @$tuple ] returns the same thing&#38;quot;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;  &lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This can be an effective way to write tests. The code that performs the actual tests is small and stays the same no matter how many tests I want to run. When I have more test cases, I add to the table of input values.&lt;/p&gt;

&lt;p&gt;As the table got larger, listing all of the combinations literally in the code became a problem. I&#38;#39;d miss some combinations, repeat others, and even if I&#38;#39;d gotten everything right, I couldn&#38;#39;t fit the table on a single screen.&lt;/p&gt;

&lt;p&gt;I had specifically avoided nested loops. That might not annoy you when there are three or four parameters, but some of the subroutines took 15 parameters. That&#38;#39;s a lot of nesting.&lt;/p&gt;

&lt;p&gt;Instead, I wanted something where I could list the possible values for each of the positions, but without having to make all of the combinations myself. That is, I wanted a way to take a cross product of sets where each result would have one element from each set. Hence, &lt;a href=&#34;https://metacpan.org/module/Set::CrossProduct&#34;&gt;Set::CrossProduct&lt;/a&gt;.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Set::CrossProduct&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( blood navel valencia )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( adanac taylor macintosh )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( 1 2 )&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;]&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;I can then use the iterator to get the next combination to check. The original implementation was the reference for correct, bug-for-bug behavior:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;New::foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;  &lt;span class=&#34;cast&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;Original::foo&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;cast&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;Arguments [ @$tuple ] returns the same thing&#38;quot;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;  &lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;It&#38;#39;s not a complicated module behind the scenes. For each of the array references, I maintain a cursor so I know which item to pick next. When I get to the end of an array reference, I go back to the start. If all the cursors are the last positions, then the iterator is spent.&lt;/p&gt;

&lt;p&gt;The more I used the module, the more uses I found for it, and the more I needed to move around the iterator. Besides getting the next element, I added methods to look around the current combination, pick a random combination, or, get all of the combination at once (it came full circle):&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;br /&gt;16:&#38;nbsp;&lt;br /&gt;17:&#38;nbsp;&lt;br /&gt;18:&#38;nbsp;&lt;br /&gt;19:&#38;nbsp;&lt;br /&gt;20:&#38;nbsp;&lt;br /&gt;21:&#38;nbsp;&lt;br /&gt;22:&#38;nbsp;&lt;br /&gt;23:&#38;nbsp;&lt;br /&gt;24:&#38;nbsp;&lt;br /&gt;25:&#38;nbsp;&lt;br /&gt;26:&#38;nbsp;&lt;br /&gt;27:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Set::CrossProduct&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ARRAY_OF_ARRAYS&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# get the number of tuples&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$number_of_tuples&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;cardinality&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# get the next tuple&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt;            &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# move back one position&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt;            &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;unget&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# get the next tuple without resetting&lt;br /&gt;# the cursor (peek at it)&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$next_tuple&lt;/span&gt;       &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# get the previous tuple without resetting&lt;br /&gt;# the cursor&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$last_tuple&lt;/span&gt;       &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;previous&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# get a random tuple&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuple&lt;/span&gt;            &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;random&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# in list context returns a list of all tuples&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@tuples&lt;/span&gt;           &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;combinations&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# in scalar context returns an array reference to all tuples&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$tuples&lt;/span&gt;           &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$iterator&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;combinations&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&#34;https://metacpan.org/module/Set::CrossProduct&#34;&gt;Set::CrossProduct&lt;/a&gt; module isn&#38;#39;t the only way to accomplish this task. The &lt;a href=&#34;https://metacpan.org/module/Algorithm::Loops&#34;&gt;Algorithm::Loops&lt;/a&gt; module has a &lt;code&gt;NestedLoops&lt;/code&gt; subroutine that can do the same thing.&lt;/p&gt;

&lt;p&gt;Some people confuse a cross product of different sets with permutations of elements in the same set. If that&#38;#39;s what you want to do, &lt;a href=&#34;https://metacpan.org/module/Algorithm::Combinatorics&#34;&gt;Algorithm::Combinatorics&lt;/a&gt; might be the right tool.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2011-12-06T00:00:00-05:00</updated><category term="Perl"/><author><name>brian d foy</name></author></entry><entry><title>Stupid Command Line Tricks</title><link href="http://perladvent.org/2011/2011-12-05.html"/><id>http://perladvent.org/2011/2011-12-05.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;The-Basics-of--M&#34;&gt;The Basics of &lt;code&gt;-M&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;perl&lt;/code&gt; understands a bunch of command line switches. Some of them, like &lt;code&gt;-f&lt;/code&gt;, you will probably never use. Others, like &lt;code&gt;-e&lt;/code&gt; and &lt;code&gt;-d&lt;/code&gt;, you might use all the time. The &lt;code&gt;-M&lt;/code&gt; switch is somewhere in between. You might use it in the most trivial case, but it can probably do a lot more than you know it can.&lt;/p&gt;

&lt;p&gt;The general use case is this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;perl -MCarp::Always::Color some-script.pl&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The general effect is that &#38;quot;&lt;code&gt;use Carp::Always::Color;&lt;/code&gt;&#38;quot; is injected at the beginning of the program to be run, as if it had been in the source itself. It&#38;#39;s great for things that affect the global execution environment, like &lt;a href=&#34;http://perladvent.org/2011/2011-12-04.html&#34;&gt;Carp::Always&lt;/a&gt;, but it&#38;#39;s got a bunch of other little uses.&lt;/p&gt;

&lt;h3 id=&#34;Importing&#34;&gt;Importing&lt;/h3&gt;

&lt;p&gt;If you want to write a one-liner that needs an import, for example, you can use the equals sign:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;perl -MList::Util=first -E &#38;#39;say first { /rjbs/ } @INC&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The string after the &lt;code&gt;=&lt;/code&gt; is passed to List::Util&#38;#39;s &lt;code&gt;import&lt;/code&gt; routine. If it has commas, the string is split on commas and the result is passed in.&lt;/p&gt;

&lt;p&gt;This is how &lt;a href=&#34;http://perladvent.org/2011/2011-12-01.html&#34;&gt;local::lib&lt;/a&gt;&#38;#39;s one-liner form works! local::lib has a tricky &lt;code&gt;import&lt;/code&gt; routine, and you pass it a path name by using &lt;code&gt;-M&#38;hellip;=&#38;hellip;&lt;/code&gt;&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;perl -Mlocal::lib=~/local/testing&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;By default, &lt;code&gt;import&lt;/code&gt; is called with no arguments, because libraries given to the &lt;code&gt;-M&lt;/code&gt; switch are loaded with &lt;code&gt;use Module;&lt;/code&gt;. You can skip the imports by using &lt;code&gt;-m&lt;/code&gt; instead. &lt;code&gt;-mMODULE&lt;/code&gt; becomes &lt;code&gt;use Module ();&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&#34;Version-Checks&#34;&gt;Version Checks&lt;/h3&gt;

&lt;p&gt;Usually, if I want to know what version(s) of a module I have installed, I run &lt;a href=&#34;https://metacpan.org/module/which_pm&#34;&gt;which_pm&lt;/a&gt;, but when I don&#38;#39;t have it &#38;ndash; or more likely, when giving advice to someone on IRC, I can use &lt;code&gt;-M&lt;/code&gt;. If I think someone&#38;#39;s seeing a bug because they&#38;#39;ve got an old version of Sub::Exporter, I can tell them to run:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -MSub::Exporter\ 999&lt;br /&gt;Sub::Exporter version 999 required--this is only version 0.982.&lt;br /&gt;BEGIN failed--compilation aborted.&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h3 id=&#34;no-MODULE&#34;&gt;&lt;code&gt;no MODULE&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Most of the time, we load libraries with &lt;code&gt;use&lt;/code&gt;, but &lt;code&gt;&lt;a href=&#34;https://metacpan.org/module/perlfunc#no&#34;&gt;no&lt;/a&gt;&lt;/code&gt; is useful, too. (Instead of calling &lt;code&gt;import&lt;/code&gt;, it calls &lt;code&gt;unimport&lt;/code&gt;.) Mostly, &lt;code&gt;no&lt;/code&gt; is used by libraries that are loaded to forbid undesirable behavior. &lt;a href=&#34;https://metacpan.org/module/indirect&#34;&gt;indirect&lt;/a&gt; lets you ban indirect method invocation. &lt;a href=&#34;https://metacpan.org/module/circular::require&#34;&gt;circular::require&lt;/a&gt; lets you ban circular module loading.&lt;/p&gt;

&lt;p&gt;In your source for &lt;i&gt;Foo.pm&lt;/i&gt;, you might write:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;warnings&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;no&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;circular::require&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Bar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# if Bar tries to &#38;quot;use Foo&#38;quot;, we&#39;ll die because of no circular::require&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...but circular::require affects the global behavior of &lt;code&gt;require&lt;/code&gt;. You probably don&#38;#39;t want to always load it everywhere. You just want to use it sometimes when testing. You can&#38;#39;t say &lt;code&gt;-Mcircular::require&lt;/code&gt;, because that would use &lt;code&gt;use&lt;/code&gt; instead of &lt;code&gt;no&lt;/code&gt;. To get &lt;code&gt;no&lt;/code&gt;, just throw in another dash:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -M-circular::require -MFoo -e0&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The code above will be silent if Foo has no circular requirements, and emit a string of warnings of it has them.&lt;/p&gt;

&lt;h2 id=&#34;Further-Madness&#34;&gt;Further Madness&lt;/h2&gt;

&lt;p&gt;So, for testing versions, I showed:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -MString::Truncate\ 999&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;For importing, I showed:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -MString::Truncate=trunc,elide -e &#38;#39;...&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;What if we want to combine these? They&#38;#39;re not really compatible. What if we want to pass something more complex than a list of strings? The bits after the equals sign aren&#38;#39;t &lt;code&gt;eval&lt;/code&gt;ed, so they can&#38;#39;t be complex.&lt;/p&gt;

&lt;p&gt;The secret lies in understanding how that version-testing code worked. The space after &#38;quot;String::Truncate&#38;quot; and everything following that is just tacked into the template &lt;code&gt;use MODULE REST ;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means you can put &lt;i&gt;almost anything&lt;/i&gt; there. Do you want to import a renamed version of &lt;code&gt;trunc&lt;/code&gt;, but only if you have a recent version?&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -M&#38;#39;String::Truncate 1.100000 trunc =&#38;gt; { -as =&#38;gt; &#38;quot;truncate&#38;quot; }&#38;#39; -e ...&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Your program will be run with the following line of code prepended:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;float&#34;&gt;1.1000&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;-as&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;truncate&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This is where it gets a little nutty: &lt;code&gt;perl&lt;/code&gt; doesn&#38;#39;t care whether you give it more than one statement. You can put all kinds of stuff in &lt;code&gt;-M&lt;/code&gt;&#38;#39;s argument. In fact, if the stuff you want to put in is important, but the module isn&#38;#39;t, you can just use something meaningless like &lt;code&gt;5&lt;/code&gt;:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -M&#38;#39;5; warn &#38;quot;pid: $$\n&#38;quot;&#38;#39; your-actual-program.pl&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The &lt;code&gt;use 5&lt;/code&gt; just ensures that you&#38;#39;re under Perl 5 or later, and then the code you actually wanted to inject is added.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-M&lt;/code&gt; is a powerful tool for all kinds of code injection when you don&#38;#39;t want to actually start editing the code you&#38;#39;re running. Even better, once you&#38;#39;ve finished working with it, you can just delete your shell history file, and nobody will know the kind of horrible things you did with it.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/perlrun&#34;&gt;perlrun&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&lt;a href=&#34;https://metacpan.org/module/perlfunc#use&#34;&gt;use&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&lt;a href=&#34;https://metacpan.org/module/perlfunc#no&#34;&gt;no&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Module::Which&#34;&gt;Module::Which&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-05T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Warn Different</title><link href="http://perladvent.org/2011/2011-12-04.html"/><id>http://perladvent.org/2011/2011-12-04.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;You-Need-Carp::Always&#34;&gt;You Need Carp::Always&lt;/h2&gt;

&lt;p&gt;I was making a list of libraries to try to cover in this year&#38;#39;s Advent calendar, and so I tried to think of the most useful stuff I could. I tried to think of libraries without which I&#38;#39;d be lost. The first thing I thought of was Carp::Always &#38;ndash; but it was a dumb idea. &lt;i&gt;Obviously&lt;/i&gt;, it would have been covered already. Maybe a few times.&lt;/p&gt;

&lt;p&gt;After I&#38;#39;d made my list and gotten started, though, something inside urged me to double-check. I brought up the &lt;a href=&#34;http://perladvent.org/archives-AZ.html&#34;&gt;big master Advent index&lt;/a&gt; and was shocked &#38;ndash; &lt;i&gt;&lt;b&gt;shocked!&lt;/b&gt;&lt;/i&gt; &#38;ndash; to find no entry for Carp::Always. (Frankly, I was surprised not to see Carp, either, but there isn&#38;#39;t all that much coverage of the core in the index. Maybe we&#38;#39;ll have to work on that&#38;hellip;)&lt;/p&gt;

&lt;p&gt;Then I almost gave up anyway, because &lt;i&gt;of course&lt;/i&gt; everyone knows about Carp::Always. Suddenly, though, I was overwhelmed with a stream of memories all working like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &#38;lt;rjbs&#38;gt; Anyway, just try it with Carp::Always.
  &#38;lt;dude&#38;gt; What&#38;#39;s Carp::Always?
  &#38;lt;rjbs&#38;gt; ????????&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, let&#38;#39;s get to it.&lt;/p&gt;

&lt;h2 id=&#34;Death-Croaking-and-Confession&#34;&gt;Death, Croaking, and Confession&lt;/h2&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Common&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;func&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;func is unimplemented&#38;quot;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Program&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;minor_system&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Common::func&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;90&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;70&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;subroutine&lt;/span&gt;   &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;minor_system&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;run&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;subroutine&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;123&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;Program&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Here&#38;#39;s a ridiculously simple, pointless program. Well, not quite pointless: it exists just to build some simple call stack, and then die a few frames down it.&lt;/p&gt;

&lt;p&gt;We get an error like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  func is unimplemented at program.pl line 4.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you pretend that Common is actually some library that&#38;#39;s getting called all over the place, you can imagine how the error above is just about the &lt;i&gt;least useful thing ever&lt;/i&gt;. Yeah, great. You go look up the error and find that it&#38;#39;s from inside one of the most-used parts of your whole program. What&#38;#39;s calling it? Well, you could start adding print statements, or maybe inspect &lt;code&gt;caller&lt;/code&gt;, but you could just replace that &lt;code&gt;die&lt;/code&gt; with a &lt;code&gt;croak&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;croak&lt;/code&gt;, provided by &lt;a href=&#34;https://metacpan.org/module/Carp&#34;&gt;Carp&lt;/a&gt;, is just like &lt;code&gt;die&lt;/code&gt;, but instead of reporting the line and file where the exception is thrown, it tells you what called the routine that died. In the great majority of cases, this is much more useful. Unless you&#38;#39;re using &lt;code&gt;die&lt;/code&gt; to print a user-visible error for a command line program, you should probably be using &lt;code&gt;croak&lt;/code&gt; instead of &lt;code&gt;die&lt;/code&gt; all the time.&lt;/p&gt;

&lt;p&gt;If we add a &lt;code&gt;use Carp;&lt;/code&gt; line at line 3 and switch our exception to &lt;code&gt;croak&lt;/code&gt;, we get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  func is unimplemented at program.pl line 8&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Despite looking almost the same, this is much more useful! We can go back to our code, find line 8, and see that the error is coming from that &lt;i&gt;particular&lt;/i&gt; call to &lt;code&gt;func&lt;/code&gt;. If our code was calling it all over the place, this would eliminate a huge mess of hunting around.&lt;/p&gt;

&lt;p&gt;So, already, knowing how to use the stuff in Carp is a huge win &#38;ndash; but I haven&#38;#39;t talked about all of it, just &lt;code&gt;croak&lt;/code&gt;, which is like &lt;code&gt;die&lt;/code&gt;. There&#38;#39;s also &lt;code&gt;carp&lt;/code&gt;, which is like &lt;code&gt;warn&lt;/code&gt;. The other two similar functions in Carp are &lt;code&gt;confess&lt;/code&gt; and &lt;code&gt;cluck&lt;/code&gt;. They act like &lt;code&gt;die&lt;/code&gt; and &lt;code&gt;warn&lt;/code&gt;, respectively, but provide the whole stack trace.&lt;/p&gt;

&lt;p&gt;See, imagine that our stupidly simple example program was a dozen or more packages, with calls going from one to the other in different orders and forming all kinds of different stacks. Finding out that the caller of &lt;code&gt;func&lt;/code&gt; was &lt;code&gt;Program::minor_system&lt;/code&gt; wouldn&#38;#39;t actually be that big of a deal, because we&#38;#39;d want the caller of that, and the next one, too.&lt;/p&gt;

&lt;p&gt;We could go into our code for Common and replace &lt;code&gt;croak&lt;/code&gt; with &lt;code&gt;confess&lt;/code&gt;, and now we&#38;#39;d get something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  func is unimplemented at program.pl line 4
    Common::func() called at program.pl line 8
    Program::minor_system() called at program.pl line 9
    Program::subroutine(123) called at program.pl line 12
    Program::run(&#38;#39;Program&#38;#39;) called at program.pl line 16&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;Doesnt-everybody-love-stack-traces-&#34;&gt;Doesn&#38;#39;t everybody love stack traces?&lt;/h2&gt;

&lt;p&gt;It turns out, not everybody loves seeing stack traces all the time. If you use &lt;a href=&#34;http://moose.perl.org/&#34;&gt;Moose&lt;/a&gt;, you&#38;#39;ve probably already got a complex set of feelings about stack traces. You might think things like, &#38;quot;this isn&#38;#39;t alway very useful&#38;quot; or &#38;quot;what the hell am I supposed to do with this?&#38;quot; or &#38;quot;boy, am I ever sick of stack traces!&#38;quot;&lt;/p&gt;

&lt;p&gt;So, maybe you don&#38;#39;t &lt;i&gt;want&lt;/i&gt; &lt;code&gt;func&lt;/code&gt; to use &lt;code&gt;confess&lt;/code&gt;. Maybe most of the time, it would actually be a huge drag. Sometimes, though, you do want it, and you don&#38;#39;t want to have to go edit the source just to get it. This is where &lt;a href=&#34;https://metacpan.org/module/Carp::Always&#34;&gt;Carp::Always&lt;/a&gt; comes in.&lt;/p&gt;

&lt;p&gt;If we revert our program to the version that used &lt;code&gt;die&lt;/code&gt;, but then run like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ perl -MCarp::Always program.pl&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...we get a stack trace, and it looks just like the one above! We have to be a bit wary of these Carp::Always-provided stack traces, though. Carp::Always works by adding a &lt;code&gt;__DIE__&lt;/code&gt; handler, which is tricky stuff. Sometimes, you get bogus output. For example, if we use &lt;code&gt;croak&lt;/code&gt; in our program &lt;i&gt;and&lt;/i&gt; run with &lt;code&gt;-MCarp::Always&lt;/code&gt; we get a duplicated stack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  func is unimplemented at program.pl line 4
    Common::func() called at program.pl line 8
    Program::minor_system() called at program.pl line 9
    Program::subroutine(123) called at program.pl line 12
    Program::run(&#38;#39;Program&#38;#39;) called at program.pl line 4
    Common::func() called at program.pl line 8
    Program::minor_system() called at program.pl line 9
    Program::subroutine(123) called at program.pl line 12
    Program::run(&#38;#39;Program&#38;#39;) called at program.pl line 16&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oops! This can be a big problem, but in practice it&#38;#39;s not all that likely. Still, you have to keep in mind that it&#38;#39;s not foolproof.&lt;/p&gt;

&lt;p&gt;Keep in mind that Carp::Always doesn&#38;#39;t just convert die and croak to confess. It also converts warn and carp to cluck. That means that if your program throws a bunch of warnings before it finally dies, you&#38;#39;re potentially going to start seeing huge streams of stack traces, all blending together. To deal with that, you can use &lt;a href=&#34;https://metacpan.org/module/Carp::Always::Color&#34;&gt;Carp::Always::Color&lt;/a&gt;, which breaks the traces up by colorizing the message part of the first line of each warning or error: warnings become yellow, errors become red. This makes it easy to scan over the error output to see just what happened, where, and maybe even why.&lt;/p&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Carp::Always&#34;&gt;Carp::Always&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Carp&#34;&gt;Carp&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Carp::Always::Color&#34;&gt;Carp::Always::Color&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-04T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Keep it Clean</title><link href="http://perladvent.org/2011/2011-12-03.html"/><id>http://perladvent.org/2011/2011-12-03.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;The-Big-Mess&#34;&gt;The Big Mess&lt;/h2&gt;

&lt;p&gt;Perl object orientation is a nice&#38;sup1; simple toolkit. You just put some subroutines into a package and they become methods:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do_stuff&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$argument&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$self method &#39;do_stuff&#39; received argument $argument&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The problem is, we&#38;#39;re adding subroutines to packages all the time that probably shouldn&#38;#39;t be methods:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;File::ShareDir&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(dist_dir)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(trunc)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;do_stuff&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...and then much later...&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;word&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# equivalent to trunc( MyClass-&#38;gt;new, 5 );&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;See, the problem is that when you import subroutines into your class, they become methods. The ones above might not seem too bad, but quite often these non-method imports can lead to confusion:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Date&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Moose&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;comes_before&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$other_date&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # returns true if the date $self comes before $other_date on the calendar&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;...but later, someone misremembers the name of &lt;code&gt;comes_before&lt;/code&gt; and writes this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$date&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;before&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$other_date&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This does something bizarre, because &lt;code&gt;before&lt;/code&gt; ends up referring to Moose&#38;#39;s &lt;code&gt;before&lt;/code&gt;, used to apply method modifiers to a method.&lt;/p&gt;

&lt;p&gt;To avoid these kinds of mistakes, one policy &#38;ndash; and one to which I often adhere &#38;ndash; is to not import anything. So, don&#38;#39;t write this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(trunc)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$str&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Instead, write:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;();&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# don&#39;t even call -&#38;gt;import&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;String::Truncate::trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$str&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This makes it very clear where the routines live, but it&#38;#39;s also a real drag to type, especially if you&#38;#39;re going to use &lt;code&gt;trunc&lt;/code&gt; over and over. Another solution is to use &lt;a href=&#34;http://advent.rjbs.manxome.org/2009/2009-12-01.html&#34;&gt;Sub::Exporter&lt;/a&gt; or, if the module you&#38;#39;re importing from uses Exporter, to use &lt;a href=&#34;http://advent.rjbs.manxome.org/2010/2010-12-02.html&#34;&gt;Sub::Import&lt;/a&gt;. Then you could say something like this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;-as&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_trunc&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;_trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$str&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;With this formula, &lt;code&gt;$obj-&#38;gt;_trunc&lt;/code&gt; will still work as a method call, but at least you can blame the programmer who tried calling a private method on your object... but remember that it might be you.&lt;/p&gt;

&lt;h2 id=&#34;Cleaning-Up&#34;&gt;Cleaning Up&lt;/h2&gt;

&lt;p&gt;Rather than just never import, though, you can take an alternate route: you can delete the imported subroutines from the symbol table after you&#38;#39;ve bound to them. In other words:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;br /&gt;15:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MyClass&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;String::Truncate&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(trunc)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$MyClass::&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# or one of many other ways to do it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;real_method&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$self&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@arg&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # ...&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$str&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;trunc&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$str&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;  # ...&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;If you do this, then later, &lt;code&gt;$obj-&#38;gt;trunc&lt;/code&gt; will fail, finding no method. The call to &lt;code&gt;trunc&lt;/code&gt; inside &lt;code&gt;real_method&lt;/code&gt; still works, though, because the symbol &lt;code&gt;trunc&lt;/code&gt; (at line 12) is bound to the installed routine at &lt;i&gt;compile&lt;/i&gt; time, but the &lt;code&gt;delete&lt;/code&gt; (at line 5) is not executed until &lt;i&gt;run time&lt;/i&gt;. This is a big drag, though, because you have to account for all the stuff you imported and delete it all again.&lt;/p&gt;

&lt;p&gt;That&#38;#39;s why we have &lt;a href=&#34;https://metacpan.org/module/namespace::clean&#34;&gt;namespace::clean&lt;/a&gt;. We could replace the delete in the code above with &lt;code&gt;use namespace::clean&lt;/code&gt;. It would make a note that once the compile phase was over, all the subroutines defined before the &lt;code&gt;use&lt;/code&gt; would get deleted. That means that if you put all your subroutine-importing &lt;code&gt;use&lt;/code&gt; statements above namespace::clean, they&#38;#39;d all be purged and wouldn&#38;#39;t be callable as methods.&lt;/p&gt;

&lt;p&gt;Unfortunately, you might be importing some stuff that &lt;i&gt;should&lt;/i&gt; be a method. Going back to Moose, for example, you don&#38;#39;t want the &lt;code&gt;meta&lt;/code&gt; method that you get from &lt;code&gt;use Moose&lt;/code&gt; to get cleaned up. It would break... well, pretty much everything. Further, if you&#38;#39;re going to have to purge more than one hunk of imports, you have to start doing some annoying accounting and use of &lt;code&gt;no namespace::clean&lt;/code&gt;. See the &lt;a href=&#34;https://metacpan.org/module/namespace::clean#SYNOPSIS&#34;&gt;namespace::clean synopsis&lt;/a&gt; for a short example.&lt;/p&gt;

&lt;p&gt;So, the next upgrade from namespace::clean is &lt;a href=&#34;https://metacpan.org/module/namespace::autoclean&#34;&gt;namespace::autoclean&lt;/a&gt;. Once you use it anywhere in your program, it will wait around until the compile phase is over, and will then look at &lt;i&gt;all&lt;/i&gt; the subroutines in the package. It decides&#38;sup2; which ones are methods and which ones are not, and then purges all the non-methods. This makes it much better at just doing the right thing without making you think about it. It won&#38;#39;t purge &lt;code&gt;meta&lt;/code&gt;, it won&#38;#39;t get confused because you accidentally move one of your subroutine-importing &lt;code&gt;use&lt;/code&gt; statements below it. The down side is that because it uses Class::MOP, it&#38;#39;s got a decent-sized memory and compile-speed overhead. I&#38;#39;m almost always using Moose, though, so the cost is tiny compared to the sanity it provides.&lt;/p&gt;

&lt;h2 id=&#34;Importing-Methods&#34;&gt;Importing Methods&lt;/h2&gt;

&lt;p&gt;Finally, I should note that sometimes you &lt;i&gt;do&lt;/i&gt; want to import something so that it can be called as a method. Maybe you&#38;#39;re using a library that exports subroutines that expect to be methods &#38;ndash; &lt;a href=&#34;https://metacpan.org/module/Data::Section&#34;&gt;Data::Section&lt;/a&gt;, for example. In these cases, if you&#38;#39;re using namespace::autoclean, you&#38;#39;ll need to make sure the subroutines get installed properly so that they won&#38;#39;t be purged. &lt;a href=&#34;https://metacpan.org/module/Sub::Exporter::ForMethods&#34;&gt;Sub::Exporter::ForMethods&lt;/a&gt; exists for just this reason:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sub::Exporter::ForMethods&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( method_installer )&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::Section&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;installer&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;method_installer&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;-setup&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h3 id=&#34;Footnotes&#34;&gt;Footnotes&lt;/h3&gt;

&lt;ol&gt;

&lt;li&gt;&lt;p&gt;Well, not everyone agrees it&#38;#39;s nice.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It uses the logic in &lt;a href=&#34;https://metacpan.org/module/Class::MOP::Mixin::HasMethods&#34;&gt;Class::MOP::Mixin::HasMethods&lt;/a&gt;&#38;#39;s &lt;code&gt;_code_is_mine&lt;/code&gt;, if you want to start seeing how it works &#38;ndash; but that&#38;#39;s a private method and might move around or change.&lt;/p&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/namespace::autoclean&#34;&gt;namespace::autoclean&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/namespace::clean&#34;&gt;namespace::clean&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-03T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Keeping up with the Joneses</title><link href="http://perladvent.org/2011/2011-12-02.html"/><id>http://perladvent.org/2011/2011-12-02.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Restoring-the-Features-of-Yore&#34;&gt;Restoring the Features of Yore&lt;/h2&gt;

&lt;p&gt;Back in the day, there were two choices for installing code from the CPAN: the original &lt;a href=&#34;https://metacpan.org/module/CPAN&#34;&gt;CPAN&lt;/a&gt; client and &lt;a href=&#34;https://metacpan.org/module/CPANPLUS&#34;&gt;CPANPLUS&lt;/a&gt;. Innovation in one kept driving the other, and by the release of perl-5.10, both had sprouted all kinds of features and usability enhancements. They&#38;#39;d also gotten easier to use, but maybe not easy enough. When &lt;a href=&#34;https://metacpan.org/author/MIYAGAWA&#34;&gt;Miyagawa&lt;/a&gt; released &lt;a href=&#34;https://metacpan.org/module/App::cpanminus&#34;&gt;App::cpanminus&lt;/a&gt; (aka &lt;code&gt;cpanm&lt;/code&gt;), there was much rejoicing, and it&#38;#39;s become incredibly popular in its two short years of life.&lt;/p&gt;

&lt;p&gt;One of the reasons that &lt;code&gt;cpanm&lt;/code&gt; has remained so easy to use is that it jettisons huge numbers of the advanced features of &lt;code&gt;CPAN&lt;/code&gt; and &lt;code&gt;CPANPLUS&lt;/code&gt;. Some of these are only needed for pretty exotic configurations like automated testers or enterprise environments. A few, though, were pretty useful for everybody. My favorite were probably the &lt;code&gt;r&lt;/code&gt; and &lt;code&gt;upgrade&lt;/code&gt; commands in the CPAN shell.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;r&lt;/code&gt; (which as far as I know has no longer name) prints out a report on installed modules that aren&#38;#39;t the latest version. For example, if I run it right now, I see this:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;br /&gt;11:&#38;nbsp;&lt;br /&gt;12:&#38;nbsp;&lt;br /&gt;13:&#38;nbsp;&lt;br /&gt;14:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;cpan[1]&#38;gt; r&lt;br /&gt;CPAN: Storable loaded ok (v2.30)&lt;br /&gt;Reading &#38;#39;/Users/rjbs/.cpan/Metadata&#38;#39;&lt;br /&gt;&#38;nbsp;&#38;nbsp;Database was generated on Thu, 03 Nov 2011 03:30:30 GMT&lt;br /&gt;CPAN: Module::CoreList loaded ok (v2.57)&lt;br /&gt;&lt;br /&gt;Package namespace              installed    latest  in CPAN file&lt;br /&gt;Getopt::Lucid                      undef      0.19  DAGOLDEN/Getopt-Lucid-0.19.tar.gz&lt;br /&gt;AnyDBM_File                         1.00      1.01  FLORA/perl-5.15.4.tar.gz&lt;br /&gt;HTML::Mason::Apache::Request       undef         0  DROLSKY/HTML-Mason-1.47.tar.gz&lt;br /&gt;Number::Tolerant::Type::constant   undef     1.700  RJBS/Number-Tolerant-1.700.tar.gz&lt;br /&gt;PerlIO::scalar                      0.11      0.12  RJBS/perl-5.15.2.tar.bz2&lt;br /&gt;1224 installed modules have no parsable version number&lt;br /&gt;(use &#38;#39;o conf show_unparsable_versions 1&#38;#39; to show them)&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;The &lt;code&gt;upgrade&lt;/code&gt; command finds the same list, but instead of just printing it out, it installs all the new code.&lt;/p&gt;

&lt;p&gt;These have several good uses. The first one is obvious: you can keep your whole installed development environment up to date with the latest releases. This is maybe a little crazy for your production environment, but if you&#38;#39;re installing to a &lt;a href=&#34;http://perladvent.org/2011/2011-12-01.html&#34;&gt;local::lib&lt;/a&gt;, it&#38;#39;s a great way to test your code against a full upgrade. It&#38;#39;s also great for debugging. When I get a bug report that I can&#38;#39;t reproduce, I often ask the reporting user to show me the output of a report like this. I compare it to mine, and half the time I see a relevant different: the user has an older Moose, I have an older Params::Validate, or something along those lines.&lt;/p&gt;

&lt;p&gt;This kind of feature is great, but it&#38;#39;s totally outside the realm of stuff that &lt;code&gt;cpanm&lt;/code&gt; is ever going to do. That doesn&#38;#39;t mean we need to go back to the old clients just yet, because &lt;a href=&#34;https://metacpan.org/author/TOKUHIROM&#34;&gt;Tokuhiro Matsuno&lt;/a&gt; wrote &lt;a href=&#34;https://metacpan.org/module/App::cpanoutdated&#34;&gt;App::cpanoutdated&lt;/a&gt;. It does the work of &lt;a href=&#34;https://metacpan.org/module/CPAN&#34;&gt;CPAN&lt;/a&gt;&#38;#39;s &lt;code&gt;r&lt;/code&gt; command:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ cpan-outdated&lt;br /&gt;Z/ZE/ZEFRAM/Devel-Declare-0.006008.tar.gz&lt;br /&gt;R/RJ/RJBS/Dist-Zilla-Plugin-CheckPrereqsIndexed-0.006.tar.gz&lt;br /&gt;G/GE/GETTY/HTTP-Body-1.14.tar.gz&lt;br /&gt;S/SM/SMUELLER/YAML-Syck-1.18.tar.gz&lt;br /&gt;M/MS/MSCHILLI/Log-Log4perl-1.34.tar.gz&lt;br /&gt;S/SM/SMUELLER/PAR-Dist-0.48.tar.gz&lt;br /&gt;R/RJ/RJBS/Test-Fatal-0.008.tar.gz&lt;br /&gt;S/SA/SADAHIRO/Unicode-Collate-0.84.tar.gz&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;This is a less information than the &lt;code&gt;r&lt;/code&gt; command. It doesn&#38;#39;t tell us what the relevant module is, or what version we have installed, but it turns out that this is generally enough. It still tells you which dists are out of date, which is just about as good as which modules. (You also might note that it&#38;#39;s a different set of dists. That&#38;#39;s because I had to run these commands on different installs, because I haven&#38;#39;t kept my own &lt;code&gt;cpan&lt;/code&gt; working very well since I switched to &lt;code&gt;cpanm&lt;/code&gt;! That&#38;#39;s all.)&lt;/p&gt;

&lt;p&gt;It has another great property, too: you can pipe the output of &lt;code&gt;cpan-outdated&lt;/code&gt; to &lt;code&gt;cpanm&lt;/code&gt;.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ cpan-outdated | cpanm&lt;br /&gt;[ &#38;hellip; ]&lt;br /&gt;8 distributions installed&lt;br /&gt;~$ cpan-outdated&lt;br /&gt;~$&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::cpanoutdated&#34;&gt;App::cpanoutdated&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/App::cpanminus&#34;&gt;App::cpanminus&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-02T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry><entry><title>Keeping the Packages Neatly Wrapped Up</title><link href="http://perladvent.org/2011/2011-12-01.html"/><id>http://perladvent.org/2011/2011-12-01.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;h2 id=&#34;Who-the-heck-installed-WWW::AdventCalendar-on-the-server-&#34;&gt;Who the heck installed WWW::AdventCalendar on the server?&lt;/h2&gt;

&lt;p&gt;Imagine this not-exactly-hypothetical conversation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &#38;lt;Alice&#38;gt; Who the heck installed WWW::AdventCalendar on the server?
  &#38;lt;Bob&#38;gt;   I did.  Why?
  &#38;lt;Alice&#38;gt; We&#38;#39;re trying to set up a new server just like it, and we found
          this installed, and it wants all kinds of crazy prerequisites.
          Why on Earth do we need this in production?
  &#38;lt;Bob&#38;gt;   Oh, we don&#38;#39;t.  I just wanted to play around with it.
  &#38;lt;Alice&#38;gt; ...so you installed it globally?
  &#38;lt;Bob&#38;gt;   Well, how else was I going to play with it?&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, I&#38;#39;m not going to defend Bob here, and say that he was just trying to use a really cool program, or that he is a really decent coworker who only made this mistake a couple times and other times comes in right on schedule and doesn&#38;#39;t make waves, or that he probably deserves some time off and a desk that isn&#38;#39;t right under the air conditioning vent. None of that would be relevant.&lt;/p&gt;

&lt;p&gt;I&#38;#39;m just going to say that sometimes it seems a lot easier to just globally install some stupid library to play with it than to do something else. After all, what&#38;#39;s the alternative?&lt;/p&gt;

&lt;p&gt;Well, you can download the tarball, extract it, and so on, something like:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ curl http://cpan.metacpan.org/authors/id/R/RJ/RJBS/WWW-AdventCalendar-1.102.tar.gz&lt;br /&gt;$ tar zxvf WWW-AdventCalendar-1.102.tar.gz&lt;br /&gt;$ cd WWW-AdventCalendar&lt;br /&gt;$ perl Makefile.PL&lt;br /&gt;[ ... ]&lt;br /&gt;$ make&lt;br /&gt;$ perl -I lib -MWWW::AdventCalendar -e &#38;#39;...&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Yes. You can do that, but there are two problems. First off, it&#38;#39;s already much, much more annoying than just:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ cpanm WWW::AdventCalendar&lt;br /&gt;$ perl -MWWW::AdventCalendar -e &#38;#39;...&#38;#39;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;Secondly, it won&#38;#39;t work, anyway, because the &lt;code&gt;[ ... ]&lt;/code&gt; in my snippet above would include things like missing prerequisites. Lots of them.&lt;/p&gt;

&lt;p&gt;Well, you could get each one in turn, and end up with a dozen &lt;code&gt;-I&lt;/code&gt; options on your oneliner. But that won&#38;#39;t work either, because some of them will be XS libraries, so they&#38;#39;ll have compiled C code, so you&#38;#39;ll need to use &lt;code&gt;-Mblib&lt;/code&gt;, and who ever gets that working right across a bunch of paths?&lt;/p&gt;

&lt;p&gt;So, &lt;code&gt;cpanm&lt;/code&gt; it is, right?&lt;/p&gt;

&lt;p&gt;Yes, actually!&lt;/p&gt;

&lt;h2 id=&#34;Look-Ma-no-sudo-&#34;&gt;Look, Ma, no &lt;code&gt;sudo&lt;/code&gt;!&lt;/h2&gt;

&lt;p&gt;Of course, if you tried to use &lt;code&gt;cpanm&lt;/code&gt; as it stands, it will probably complain that you don&#38;#39;t have write permissions to &lt;code&gt;@INC&lt;/code&gt;, so you can&#38;#39;t properly install the library globally. You can re-run as &lt;code&gt;cpanm -S&lt;/code&gt;, and you&#38;#39;ll be prompted to authenticate for &lt;code&gt;sudo&lt;/code&gt;. Now everything installs nicely! See, this is how Bob gets himself in trouble. He just wants things to work nicely. Is that so wrong?&lt;/p&gt;

&lt;p&gt;Well, yes, probably. Bob just needs to know how to make things work nicely &lt;i&gt;without putting crap in &lt;code&gt;/usr/local/lib/perl&lt;/code&gt;&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;Actually, if you tried running &lt;code&gt;cpanm&lt;/code&gt; without telling it to authenticate to install globally, you would&#38;#39;ve gotten this somewhat overwhelming message, which you should not bother reading here:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ! Can&#38;#39;t write to /usr/pkg/lib/perl5/site_perl/5.8.0 and /usr/pkg/lib/perl5/site_perl/bin:
  ! Installing modules to /export/home/rjbs/perl5
  ! To turn off this warning, you have to do one of the following:
  !   - run me as a root or with --sudo option
  !     (to install to /usr/pkg/lib/perl5/site_perl/5.8.0 and /usr/pkg/lib/perl5/site_perl/bin)
  !   - run me with --local-lib option e.g. cpanm --local-lib=~/perl5
  !   - Set PERL_CPANM_OPT=&#38;quot;--local-lib=~/perl5&#38;quot; environment variable (in your shell rc file)
  !   - Configure local::lib in your shell to set PERL_MM_OPT etc.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Did you read it by accident? Sorry. Instead, just finish reading this article.&lt;/p&gt;

&lt;p&gt;What you really want to do is to get all the convenience of having a CPAN client install a module, including all its prereqs, with one simple command, into a compartment you can throw away when you&#38;#39;re done. This is exactly what &lt;a href=&#34;https://metacpan.org/module/local::lib&#34;&gt;local::lib&lt;/a&gt; is for.&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;$ eval `perl -Mlocal::lib=~/local/advcal`&lt;br /&gt;$ cpanm WWW::AdventCalendar&lt;br /&gt;[ ... ]&lt;br /&gt;38 distributions installed&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;local::lib adds a new set of directories to your Perl environment. With a local::lib in place, stuff installed from the CPAN will go into the local::lib, affecting your current shell, but nothing else. It&#38;#39;s actually much better than just learning how &lt;a href=&#34;https://metacpan.org/module/blib&#34;&gt;blib&lt;/a&gt; works, because it will also update your &lt;code&gt;$PATH&lt;/code&gt; so that programs installed by the libraries will work, too. When you&#38;#39;re done, you can remove the directory and log out of the shell, and everything will be back to normal.&lt;/p&gt;

&lt;p&gt;You could also leave the directory around. Most of the time, it would just sit there doing nothing, but if you wanted to play around with the code in it later, you could use the same local::lib invocation later to get that set of directories back in action.&lt;/p&gt;

&lt;p&gt;If you&#38;#39;re really lazy, like me, you could write a little shell function to make it even easier to turn on a local::lib:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;synIdentifier&#34;&gt;ll () {&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;`perl -Mlocal::&lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;lib&lt;/span&gt;=&lt;span class=&#34;synPreProc&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;`&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;How-does-it-work-&#34;&gt;How does it work?&lt;/h2&gt;

&lt;p&gt;There is a lot of tricky handling of edge cases and special horrible things inside local::lib, but for the most part it does something very simple. If we get rid of the shell &lt;code&gt;eval&lt;/code&gt;, you can see:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;~$ perl -Mlocal::lib=~/local/whatever&lt;br /&gt;Attempting to create directory /Users/rjbs/local/whatever&lt;br /&gt;export PERL_LOCAL_LIB_ROOT=&#38;quot;/Users/rjbs/local/whatever&#38;quot;;&lt;br /&gt;export PERL_MB_OPT=&#38;quot;--install_base /Users/rjbs/local/whatever&#38;quot;;&lt;br /&gt;export PERL_MM_OPT=&#38;quot;INSTALL_BASE=/Users/rjbs/local/whatever&#38;quot;;&lt;br /&gt;export PERL5LIB=&#38;quot;/Users/rjbs/local/whatever/lib/perl5/darwin:/Users/rjbs/local/whatever/lib/perl5&#38;quot;;&lt;br /&gt;export PATH=&#38;quot;/Users/rjbs/local/whatever/bin:$PATH&#38;quot;;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;After ensuring that directory exists (and possibly mentioning, on &lt;code&gt;STDOUT&lt;/code&gt;, that it had to be created), local::lib prints out a bunch of lines that, if executed in your shell, will set up environment variables that put the directory into play. It decides just what to print based on the shell you&#38;#39;re using, so &lt;code&gt;csh&lt;/code&gt; users will see &lt;code&gt;setenv&lt;/code&gt; instead of &lt;code&gt;export&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;MM_OPT&lt;/code&gt; environment variable tells &lt;a href=&#34;https://metacpan.org/module/ExtUtils::MakeMaker&#34;&gt;ExtUtils::MakeMaker&lt;/a&gt; to install inside the compartment. &lt;code&gt;MB_OPT&lt;/code&gt; passes the same information to &lt;a href=&#34;https://metacpan.org/module/Module::Build&#34;&gt;Module::Build&lt;/a&gt;. &lt;code&gt;PERL5LIB&lt;/code&gt; acts like a &lt;code&gt;use lib&lt;/code&gt; statement at the top of any Perl code you run.&lt;/p&gt;

&lt;p&gt;You can have multiple local::lib compartments active at once:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ ll local/already-there
  Attempting to create directory /Users/rjbs/local/already-there

  ~$ ll local/second-lib
  Attempting to create directory /Users/rjbs/local/second-lib

  ~$ perl -Mlocal::lib=local/three
  Attempting to create directory /Users/rjbs/local/three
  export PERL_LOCAL_LIB_ROOT=&#38;quot;$PERL_LOCAL_LIB_ROOT:/Users/rjbs/local/three&#38;quot;;
  export PERL_MB_OPT=&#38;quot;--install_base /Users/rjbs/local/three&#38;quot;;
  export PERL_MM_OPT=&#38;quot;INSTALL_BASE=/Users/rjbs/local/three&#38;quot;;
  export PERL5LIB=&#38;quot;/Users/rjbs/local/three/lib/perl5/darwin-2level:
  /Users/rjbs/local/three/lib/perl5:$PERL5LIB&#38;quot;;
  export PATH=&#38;quot;/Users/rjbs/local/three/bin:$PATH&#38;quot;;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The most recently-added compartment is the installation target, but things in the first two will still be there.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ echo $PATH
  /Users/rjbs/local/three/bin:/Users/rjbs/local/second-lib/bin:
  /Users/rjbs/local/already-there/bin:/Users/rjbs/bin:/usr/local/bin:
  /usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to take one compartment out of use, that&#38;#39;s easy, too:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ~$ perl -Mlocal::lib=--deactivate,local/second-lib
  export PERL_LOCAL_LIB_ROOT=&#38;quot;/Users/rjbs/local/already-there:/Users/rjbs/local/three&#38;quot;;
  export PATH=&#38;quot;/Users/rjbs/local/three/bin:/Users/rjbs/local/already-there/bin:/Users/rjbs/bin:
  /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin&#38;quot;;
  export PERL5LIB=&#38;quot;/Users/rjbs/local/three/lib/perl5/darwin-2level:
  /Users/rjbs/local/three/lib/perl5:/Users/rjbs/local/already-there/lib/perl5/darwin-2level:
  /Users/rjbs/local/already-there/lib/perl5&#38;quot;;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, 99% of the time, I bet you&#38;#39;ll just want the same case I want: &lt;code&gt;ll&lt;/code&gt; to start using a local::lib and logging out to stop.&lt;/p&gt;

&lt;h2 id=&#34;local::lib-the-diagnostics&#34;&gt;local::lib &#38;ndash; the diagnostics&lt;/h2&gt;

&lt;p&gt;If you&#38;#39;re like me, you&#38;#39;re often thwarted by the overly-clever formatting done by some version of GNU&#38;#39;s man-reading toolchain. It will turn &#38;quot;&#38;quot; into &#38;ldquo;&#38;rdquo; and other such things. This is particularly bad when it turns &lt;code&gt;program -X&lt;/code&gt; into &lt;code&gt;program &#38;ndash;X&lt;/code&gt; &#38;ndash; if you didn&#38;#39;t notice, that second one uses an emdash instead of a hyphen.&lt;/p&gt;

&lt;p&gt;To deal with people copying and pasting from man pages to the shell and having this problem, local::lib has one of my favorite error handling blocks that I&#38;#39;ve yet seen:&lt;/p&gt;



&lt;table class=&#39;code-listing&#39;&gt;&lt;tr&gt;&lt;td class=&#39;line-numbers&#39;&gt;&lt;br /&gt;&lt;code&gt;1:&#38;nbsp;&lt;br /&gt;2:&#38;nbsp;&lt;br /&gt;3:&#38;nbsp;&lt;br /&gt;4:&#38;nbsp;&lt;br /&gt;5:&#38;nbsp;&lt;br /&gt;6:&#38;nbsp;&lt;br /&gt;7:&#38;nbsp;&lt;br /&gt;8:&#38;nbsp;&lt;br /&gt;9:&#38;nbsp;&lt;br /&gt;10:&#38;nbsp;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;br /&gt;&lt;code&gt;&lt;span class=&#34;keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$arg&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/&#8722;/&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;heredoc&#34;&gt;&#38;lt;&#38;lt;&#39;DEATH&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;WHOA THERE! It looks like you&#39;ve got some fancy dashes in your commandline!&lt;br /&gt;These are *not* the traditional -- dashes that software recognizes. You&lt;br /&gt;probably got these by copy-pasting from the perldoc for this module as&lt;br /&gt;rendered by a UTF8-capable formatter. This most typically happens on an OS X&lt;br /&gt;terminal, but can happen elsewhere too. Please try again after replacing the&lt;br /&gt;dashes with normal minus signs.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;DEATH&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;h2 id=&#34;See-Also&#34;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/local::lib&#34;&gt;local::lib&lt;/a&gt;&lt;/p&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;</summary><updated>2011-12-01T00:00:00-05:00</updated><category term="Perl"/><author><name>Ricardo Signes</name></author></entry></feed>