<?xml version="1.0" encoding="us-ascii"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Perl Advent Calendar 2017</title><id>http://perladvent.org/2017/</id><link href="http://perladvent.org/2017/atom.xml" rel="self"/><updated>2026-02-18T19:25:34Z</updated><author><name>Mark Fowler</name></author><generator uri="https://metacpan.org/pod/XML::Atom::SimpleFeed" version="0.905">XML::Atom::SimpleFeed</generator><entry><title>Merry Christmas!</title><link href="http://perladvent.org/2017/2017-12-25.html"/><id>http://perladvent.org/2017/2017-12-25.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Merry Christmas Everybody!&lt;/p&gt;

&lt;p&gt;This year marks the 18th year the Perl Advent Calendar has been published. Who&#38;#39;da thought all those years ago when I came up with a silly idea at a Perl Mongers&#38;#39; social event we&#38;#39;d still have interesting and exciting things to talk about eighteen years on?&lt;/p&gt;

&lt;p&gt;But interesting things to cover we have! This year we&#38;#39;ve featured articles - in a rather joking fashion - on lots of core technologies that make Perl an ever better and improving language. We&#38;#39;ve talked about improvements to the core of Perl, Moose and it&#38;#39;s vast array of extensions that can make your life easier, we&#38;#39;ve discussed Perl&#38;#39;s amazing Unicode handling - one of the best languages out there for complicated handling - and we&#38;#39;ve covered tools to help you improve your programming from digging into your memory usage to validating your code with custom Perl Critic rules. We&#38;#39;ve even covered a bunch of handy little utility modules to allow you to create interactive terminal programs or quickly craft one liners that can grab and manipulate web pages and JSON data.&lt;/p&gt;

&lt;p&gt;A lot has improved in the last eighteen years in Perl and every year I continue to learn new techniques and new tools that make my life easier and better.&lt;/p&gt;

&lt;p&gt;So thanks to everyone that has been reading, and everyone who has written the modules, tools, and improvements to Perl that I get to talk about each year.&lt;/p&gt;

&lt;p&gt;Happy Holidays!&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-25T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Watching The Perl Conference</title><link href="http://perladvent.org/2017/2017-12-24.html"/><id>http://perladvent.org/2017/2017-12-24.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Now Christmas was over, the Wise Old Elf was going to go sit on a beach (in the southern hemisphere, where it was summer) and kick back with some quality eggnog.&lt;/p&gt;

&lt;p&gt;Of course, the Wise Old Elf doesn&#38;#39;t get to be wise by sitting on his laurels, so he was going to take the oppuntinty to catch up with all the videos of the presentations from &lt;a href=&#34;https://www.youtube.com/playlist?list=PLA9_Hq3zhoFxdSVDA4v9Af3iutQxLI14m&#34;&gt;The Perl Conference 2017 DC on YouTube&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/videoseries?list=PLA9_Hq3zhoFxdSVDA4v9Af3iutQxLI14m&#38;hl=en_US&#34; frameborder=&#34;0&#34; allowfullscreen&gt;&lt;/iframe&gt;&lt;/center&gt;

&lt;/p&gt;



&lt;p&gt;The only problem with his plan was that the beach he had in mind didn&#38;#39;t have very good WiFi. So he decided to try and download all the videos to his laptop first. Maybe Perl couyld help him with that?&lt;/p&gt;

&lt;h3 id=&#34;Scraping-the-playlist&#34;&gt;Scraping the playlist&lt;/h3&gt;

&lt;p&gt;Since he had &lt;a href=&#34;https://metacpan.org/module/2017-12-15.html&#34;&gt;learned about ojo&lt;/a&gt; it was easy for the Wise Old Elf to write something that would scrape the playlist webpage and print out, one line at a time, the URLs for the various videos in the playlist&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    perl -Mojo -E \
      &#38;#39;g(shift)-&#38;gt;dom(&#38;quot;.pl-video-title-link&#38;quot;)-&#38;gt;map(sub{say $_-&#38;gt;attr(&#38;quot;href&#38;quot;)})&#38;#39; \
      &#38;#39;https://www.youtube.com/playlist?list=PLA9_Hq3zhoFxdSVDA4v9Af3iutQxLI14m&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;WWW::YouTube::Download&#34;&gt;WWW::YouTube::Download&lt;/h3&gt;

&lt;p&gt;Now the Wise Old Elf had to write some code to parse the web page for each youtube video and then write some more code to download the video. Before he spent a lot of time doing that, he realized he could simply search the CPAN for such a utility. He not only found the wonderful &lt;a href=&#34;https://metacpan.org/module/WWW::YouTube::Download&#34;&gt;WWW::YouTube::Download&lt;/a&gt; module, but also the &lt;a href=&#34;https://metacpan.org/pod/distribution/WWW-YouTube-Download/script/youtube-download&#34;&gt;youtube-download&lt;/a&gt; command line utility that shipped with it.&lt;/p&gt;

&lt;p&gt;The way the command line utility works is simple; You pass &lt;code&gt;youtube-download&lt;/code&gt; a URL and it downloads the video into the current directory. For example to download Dave Rolsky&#38;#39;s &lt;a href=&#34;https://www.youtube.com/watch?v=DVKfBV2xngg&#38;amp;index=2&#38;amp;list=PLA9_Hq3zhoFxdSVDA4v9Af3iutQxLI14m&#34;&gt;lightning talk&lt;/a&gt; the Wise Old Elf would simply have to type:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    youtube-download /watch?v=DVKfBV2xngg&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But how would the Wise Old Elf run &lt;code&gt;youtube-download&lt;/code&gt; for each URL? With &lt;code&gt;xargs&lt;/code&gt;!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;   perl -Mojo -E \
     &#38;#39;g(shift)-&#38;gt;dom(&#38;quot;.pl-video-title-link&#38;quot;)-&#38;gt;map(sub{say $_-&#38;gt;attr(&#38;quot;href&#38;quot;)})&#38;#39; \
     &#38;#39;https://www.youtube.com/playlist?list=PLA9_Hq3zhoFxdSVDA4v9Af3iutQxLI14m&#38;#39;\
     | xargs -n 1 youtube-download&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The standard unix &lt;code&gt;xargs&lt;/code&gt; command line tool takes arguments on STDIN - one command line argument per line - and runs the utility (in this case &lt;code&gt;youtube-download&lt;/code&gt;) with those arguments. By specifying &lt;code&gt;-n 1&lt;/code&gt;, &lt;code&gt;xargs&lt;/code&gt; will run &lt;code&gt;youtube-download&lt;/code&gt; with one argument (i.e. will run &lt;code&gt;youtube-download&lt;/code&gt; with each URL passed to it on STDIN.)&lt;/p&gt;

&lt;h3 id=&#34;All-Done&#34;&gt;All Done&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;    --&#38;gt; Working on oka4wcsrg0c
    Downloading `oka4wcsrg0c.mp4`
    126211392/126211392 (100.00%)
    Download successful!
    --&#38;gt; Working on DVKfBV2xngg
    Downloading `DVKfBV2xngg.mp4`
    42843944/42843944 (100.00%)
    Download successful!
    --&#38;gt; Working on vQ5qWey_SO4
    Downloading `vQ5qWey_SO4.mp4`
    36677196/36677196 (100.00%)
    Download successful!&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A few minutes later - the North Pole has very good Internet - all the videos were downloaded to the Wise Old Elf&#38;#39;s computer. Now all he had to do was go stock up on the sunblock!&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-24T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Speedy Validation</title><link href="http://perladvent.org/2017/2017-12-23.html"/><id>http://perladvent.org/2017/2017-12-23.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Cheerful Candytree had just pulled an all-nighter trying to track down an elusive bug in the code. For some reason the code that loaded the sled was getting stuck, not returning anything.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;load_sled&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$present_name&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$qty&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;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;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;$present&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;get_present&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$present_name&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;operator&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Unknown present: $present_name&#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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sled&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;sled&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;keyword&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$qty&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;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;$qty&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$present&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_to_sled&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sled&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;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks good, doesn&#38;#39;t it? So why did it never terminate? After much much head scratching Cheerful tracked it down to a little addition some cheeky little elves had snuck in:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# Load inflight movies!&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$loader&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$movie&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Apparently the couple of dozen elves that accompanied Santa on his trip get bored during the long flight over the Atlantic and had decided to load twenty-two copies of a movie to put in their portable DVD players (presumably a couple were still helping steer.)&lt;/p&gt;

&lt;p&gt;Since they&#38;#39;d snuck this in without code review, they&#38;#39;d somehow managed to mix up the argument orders. And the movie they&#38;#39;d picked? The 2006 Milla Jovovich film &lt;a href=&#34;http://www.imdb.com/title/tt0259822/&#34;&gt;.45&lt;/a&gt;. Not being an integer number, and therefore never reaching zero when it was decremented, the sleigh loader had tried to load an infinite number of copies of Taylor Swift&#38;#39;s hit single &lt;a href=&#34;https://www.youtube.com/watch?v=AgFeZr5ptV8&#34;&gt;22&lt;/a&gt; instead. Ooops.&lt;/p&gt;

&lt;p&gt;The problem was quickly solved with (a) Swapping the order of the parameters in the code and (b) Giving the offending elves a severe talking to.&lt;/p&gt;

&lt;h3 id=&#34;Parameter-Validation&#34;&gt;Parameter Validation&lt;/h3&gt;

&lt;p&gt;Cheerful knew that once this bug had occurred once, it was likely to happen again. The first step was to switch to named parameters throughout the codebase:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;symbol&#34;&gt;$loader&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;qty&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;present_name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$movie&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;load_sled&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%p&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$present_name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;present_name&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;No present name&#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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$qty&lt;/span&gt;          &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;qty&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;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now at least the parameters can&#38;#39;t get mixed up! But there&#38;#39;s still the chance that &lt;code&gt;$qty&lt;/code&gt; would contain an non-interger. Cheerful would really like an exception to be thrown rather than going into a never ending loop.&lt;/p&gt;

&lt;p&gt;Maybe we could validate those parameters? The old venerable module for doing this is &lt;a href=&#34;https://metacpan.org/module/Params::Validate&#34;&gt;Params::Validate&lt;/a&gt;, which we &lt;a href=&#34;http://www.perladvent.org/2002/10th/&#34;&gt;originally covered&lt;/a&gt; in the Perl Advent Calendar over fifteen years ago.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Params::Validate&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( validate )&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;load_sled&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%p&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;validate&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;,&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;present_name&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;regex&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;regexp&#34;&gt;qr/./&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;&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;qty&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;regex&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;regexp&#34;&gt;qr/\A[1-9][0-9]*$/&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;optional&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;&#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;&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;br /&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;$present_name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;present_name&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;$qty&lt;/span&gt;          &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;qty&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;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Speed-Concerns&#34;&gt;Speed Concerns&lt;/h3&gt;

&lt;p&gt;There&#38;#39;s a couple of key problems with using Params::Validate:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;&lt;b&gt;Slow to run&lt;/b&gt;. Params::Validate can be pretty slow. Not only does it have to validate the arguments each time &lt;code&gt;load_sled&lt;/code&gt; is called, it also has to parse the arguments to &lt;code&gt;validate&lt;/code&gt; and work out exactly how it has to validate the arguments. Every. Single. Time.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;b&gt;Slow to write&lt;/b&gt;. There&#38;#39;s a lot of code inside the parameters to &lt;code&gt;validate&lt;/code&gt;, none of which is particularly easy to independently test, or after it&#38;#39;s written, easy to understand without having to re-read all the code. Our Moose and Moo attributes support a rich reusable type system for validating values, it would be awesome if we could re-use that code to avoid re-writing anything and provide clarity of intent on what the validation system is doing.&lt;/p&gt;

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

&lt;p&gt;In order to address these issues Dave Rolsky wrote a new module called &lt;a href=&#34;https://metacpan.org/module/Params::ValidationCompiler&#34;&gt;Params::ValidationCompiler&lt;/a&gt;. Let&#38;#39;s see it in action in Candytree&#38;#39;s codebase:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Params::ValidationCompiler&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( validation_for )&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;MooseX::Types::Common::String&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( NonEmptySimpleStr )&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;MooseX::Types::Common::Numeric&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( PositiveInt )&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;$validator&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;validation_for&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;params&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;word&#34;&gt;present_name&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;type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NonEmptySimpleStr&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;qty&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;type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;PositiveInt&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &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;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;&#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;&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;load_sled&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%p&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$validator&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;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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$present_name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;present_name&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;$qty&lt;/span&gt;          &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;qty&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Firstly, you&#38;#39;ll notice that Params::ValidationCompiler is using Moose types for it&#38;#39;s validation routines (though it&#38;#39;ll accept Type::Tiny or Specio types as well if you&#38;#39;re using those in your codebase instead.) This means that the code is significantly more readable than it was before, and Cheerful has a lot less code to write, maintain, and edge cases to test.&lt;/p&gt;

&lt;p&gt;Secondly, you&#38;#39;ll note that assigning default values has moved within the realm of the validation routine, meaning we don&#38;#39;t have to mess around with that stuff when we&#38;#39;re extracting our values from the hash. While we could have also done similar default handling with Params::Validate, the reason this becomes really useful with Params::ValidationCompiler is when we use the &lt;code&gt;named_to_list&lt;/code&gt; option to skip the intermediate hash altogether:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$validator&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;validation_for&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;params&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;word&#34;&gt;present_name&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;type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NonEmptySimpleStr&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;qty&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;type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;PositiveInt&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &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;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;&#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;named_to_list&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;load_sled&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;$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;&#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;$present_name&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$qty&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;$validator&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;magic&#34;&gt;@_&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The validator now returns the extracted values in the order in which they were specified in &lt;code&gt;validation_for&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The third and most striking change is that we&#38;#39;ve split the validation &lt;i&gt;compiling&lt;/i&gt; out from the actual call for validation. It&#38;#39;s now a two step process - first compile a validator when we first load our code up, once and only once, and then execute it when the subroutine is called. This is significantly quicker.&lt;/p&gt;

&lt;p&gt;One of the reasons that this is much quicker is because Params::ValidationCompiler actually &lt;i&gt;compiles&lt;/i&gt; a validator, not just builds one. Under the hood it uses &lt;a href=&#34;https://metacpan.org/module/Eval::Closure&#34;&gt;Eval::Closure&lt;/a&gt; (as we discussed &lt;a href=&#34;http://www.perladvent.org/2017/2017-12-10.html&#34;&gt;earlier in the month&lt;/a&gt;) to build Perl source code to make the fastest possible validator that validates the configuration that it was called with without introducing any extranious logic or subroutine calls. It&#38;#39;s even able to take advantage of the inlinable Moose types - Moose types that can themselves return Perl source code to implement their type checking - to bake-in that type checking directly inside that subroutine. This essentially means that Params::ValidationCompiler is as fast as if you&#38;#39;d hand-coded a subroutine with logic to explicitly check the arguments.&lt;/p&gt;

&lt;h3 id=&#34;To-Bed-Perchance-to-Dream&#34;&gt;To Bed, Perchance to Dream&lt;/h3&gt;

&lt;p&gt;Now the code was protected from crazy elves, Cherry Candytree was going to take a well earned kip. Hopefully by the time he awoke they wouldn&#38;#39;t have found another creative way to break things.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-23T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Custom Relationships with DBIx::Class</title><link href="http://perladvent.org/2017/2017-12-22.html"/><id>http://perladvent.org/2017/2017-12-22.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Today we pick up our &lt;a href=&#34;http://perladvent.org/2017/2017-12-21.html&#34;&gt;story from yesterday&lt;/a&gt; where Chestnut Emberflakes was working at break-neck speed to produce a tool that could be used to track the missed deliveries - which needed to be done before Santa completed his current orbit of the planet so he could immeditately head out with a list of what he needed to redo!&lt;/p&gt;

&lt;p&gt;The next requirement to be dropped in Emberflakes&#38;#39; lap was that the system needed a classification system to &lt;i&gt;tag&lt;/i&gt; each missed delivery with one or more reasons why the delivery was missed. This way when re-delivery was attempted Santa would know what to expect and how to overcome the issues.&lt;/p&gt;

&lt;p&gt;No problem, thought Chestnut, as he added a little more SQL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    CREATE TABLE reason (
        child_id UUID NOT NULL,
        tag TEXT NOT NULL,
        notes TEXT
    );

    ALTER TABLE ONLY reason
        ADD CONSTRAINT reason_pkey
        PRIMARY KEY (child_id, tag);

    ALTER TABLE ONLY reason
        ADD CONSTRAINT child_idfkey
        FOREIGN KEY (child_id)
        REFERENCES  child(child_id)
        DEFERRABLE;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now each child would have tags (with notes). Chestnut regenerated the DBIx::Class schema:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ dbicdump -o dump_directory=./lib \
        Prototype::Schema &#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which created a &lt;code&gt;Prototype::Schema::Result::Reason&lt;/code&gt; class, and added the extra relationship to the &lt;code&gt;Prototype::Schema::Result::Child&lt;/code&gt; class:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;pod&#34;&gt;=head2 reasons&lt;br /&gt;&lt;br /&gt;Type: has_many&lt;br /&gt;&lt;br /&gt;Related object: L&#38;lt;Prototype::Schema::Result::Reason&#38;gt;&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;has_many&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;reasons&#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;double&#34;&gt;&#38;quot;Prototype::Schema::Result::Reason&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;foreign.child_id&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;self.child_id&#38;quot;&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;word&#34;&gt;cascade_copy&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;span class=&#34;word&#34;&gt;cascade_delete&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;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;/pre&gt;

&lt;h3 id=&#34;Accessing-the-Tags-Inefficently&#34;&gt;Accessing the Tags, Inefficently&lt;/h3&gt;

&lt;p&gt;One problem that Santa had to overcome was the rogue family dog. Some dogs are protective of the household and wants to take a bite out of the stranger in the red suit. Other dogs are so happy Santa&#38;#39;s there that they need to bark to let the whole family know how exciting it all is.&lt;/p&gt;

&lt;p&gt;While dogs are always a problem, the elite team of elf problem solvers had recently come up with a sure fire solution for Santa&#38;#39;s next orbit:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;$child&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;delivery_problem_with_dog&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;break_out_the_bacon&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;/pre&gt;

&lt;p&gt;Now all Chestnut had to do was implement &lt;code&gt;delivery_problem_with_dog&lt;/code&gt;. Chestnut quickly produced a basic solution by adding an extra method to &lt;code&gt;Prototype::Schema::Result::Reason&lt;/code&gt; (below the section that said &lt;code&gt;DO NOT MODIFY THIS OR ANYTHING ABOVE&lt;/code&gt; so his code wouldn&#38;#39;t be overwritten by future updates.)&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;delivery_problem_with_dog&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rs&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;search_related&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Reason&#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;span class=&#34;word&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;dog&#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;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rs&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;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;comment&#34;&gt;# will be undef if there&#39;s no matching row&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks good, right? Well...not entirely.&lt;/p&gt;

&lt;h3 id=&#34;Performance-Woes&#34;&gt;Performance Woes&lt;/h3&gt;

&lt;p&gt;Apparently Christmas Eve is a very bad time to put extra stress on the elves&#38;#39; database server, which according to the sysadmin elves was &#38;quot;overloaded enough thank you very much without you doing a whole bunch of extra selects.&#38;quot; Chagrined Chestnut decided to try and investigate exactly what SQL DBIx::Class was sending to the database.&lt;/p&gt;

&lt;p&gt;First, he needed another test fixture. Chestnut gave his Kevin fixture a dog problem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    fixtures/Reason.json:
    [
        {
            &#38;quot;child_id&#38;quot;: &#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;,
            &#38;quot;tag&#38;quot;: &#38;quot;dog&#38;quot;
        }
    ]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once he&#38;#39;d repopulated his database from the new JSON fixtures using the script we showed you yesterday, Chestnut was ready examine what database calls DBIx::Class was making when he tried simple operations with it. The easiest way to do this is to set the &lt;code&gt;DBIC_TRACE&lt;/code&gt; environment variable which will cause DBIx::Class to print out all the SQL it&#38;#39;s executing. This can be be combined with &lt;code&gt;reply&lt;/code&gt; to give us a blow-by-blow view of what&#38;#39;s going on in the database:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ DBIC_TRACE=1 reply -Ilib -MPrototype::Schema
    0&#38;gt; my $schema = Prototype::Schema-&#38;gt;connect(&#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;); 1;
    $res[0] = 1

    1&#38;gt; my $child = $schema-&#38;gt;resultset(&#38;#39;Child&#38;#39;)-&#38;gt;find(&#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;); 1
    SELECT me.child_id, me.stocking_address_id, me.name FROM child me
    WHERE ( me.child_id = ? ):
    &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;
    $res[1] = 1

    2&#38;gt; $child-&#38;gt;delivery_problem_with_dog &#38;amp;&#38;amp; &#38;quot;yes&#38;quot;
    SELECT me.child_id, me.tag, me.notes FROM reason me
    WHERE ( ( me.child_id = ? AND tag = ? ) ):
    &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;, &#38;#39;dog&#38;#39;
    $res[2] = &#38;#39;yes&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh no! The &lt;code&gt;delivery_problem_with_dog&lt;/code&gt; is making another SQL call. While one extra call doesn&#38;#39;t seem too bad it would mean in production instead of making one call to select all the children his call would be making an extra SQL call per child! Is there any way Chestnut could optimize that?&lt;/p&gt;

&lt;h3 id=&#34;Teaching-DBIx::Class-about-delivery_problem_with_dog&#34;&gt;Teaching DBIx::Class about delivery_problem_with_dog&lt;/h3&gt;

&lt;p&gt;The problem here is that DBIx::Class isn&#38;#39;t able to bring to bear any of its smarts on the &lt;code&gt;delivery_problem_with_dog&lt;/code&gt; method because Emberflakes had implemented it just as a plain old Perl method. What he should have done instead is define a new DBIx::Class relationship that did the same thing.&lt;/p&gt;

&lt;p&gt;Creating basic relationships in DBIx::Class using the basic syntax is straight forward, but DBIx::Class is actually capable of being configured to build any join that you can create &lt;a href=&#34;https://metacpan.org/module/SQL::Abstract&#34;&gt;SQL::Abstract&lt;/a&gt; syntax for.&lt;/p&gt;

&lt;p&gt;For example, joining against the &lt;code&gt;reason&lt;/code&gt; table with a condition that the &lt;code&gt;tag&lt;/code&gt; is &lt;code&gt;dog&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;might_have&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;delviery_problem_with_dog&#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;double&#34;&gt;&#38;quot;Prototype::Schema::Result::Reason&#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;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;$args&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;&lt;br /&gt;&#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;double&#34;&gt;&#38;quot;$args-&#38;gt;{foreign_alias}.child_id&#38;quot;&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;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;-ident&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$args-&#38;gt;{self_alias}.child_id&#38;quot;&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;$args-&#38;gt;{foreign_alias}.tag&#38;quot;&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;=&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;dog&#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;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;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;/pre&gt;

&lt;p&gt;The final argument to &lt;code&gt;might_have&lt;/code&gt; can be a subroutine that should return parameters for SQL::Abstract - which it can build using the prefixes passed to it in its first argument.&lt;/p&gt;

&lt;p&gt;Running this as-is doesn&#38;#39;t change any of our performance characteristics at all:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ DBIC_TRACE=1 reply -Ilib -MPrototype::Schema
    0&#38;gt; my $schema = Prototype::Schema-&#38;gt;connect(&#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;); 1;
    $res[0] = 1

    1&#38;gt; my $child = $schema-&#38;gt;resultset(&#38;#39;Child&#38;#39;)-&#38;gt;find(&#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;); 1
    SELECT me.child_id, me.stocking_address_id, me.name FROM child me
    WHERE ( me.child_id = ? ):
    &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;
    $res[1] = 1

    2&#38;gt; $child-&#38;gt;delivery_problem_with_dog &#38;amp;&#38;amp; &#38;quot;yes&#38;quot;
    SELECT me.child_id, me.tag, me.notes FROM reason me
    WHERE ( ( me.child_id = ? AND tag = ? ) ):
    &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;, &#38;#39;dog&#38;#39;
    $res[2] = &#38;#39;yes&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But now DBIx::Class understands the new relationship we can ask it to do much more for us - like prefetching the value of &lt;code&gt;delivery_problem_with_dog&lt;/code&gt; when it fetches the Child in the first place!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ DBIC_TRACE=1 reply -Ilib -MPrototype::Schema
    0&#38;gt; my $schema = Prototype::Schema-&#38;gt;connect(&#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;); 1;
    $res[0] = 1

    1&#38;gt; my $child = $schema-&#38;gt;resultset(&#38;#39;Child&#38;#39;)-&#38;gt;find(&#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;,
       { prefetch =&#38;gt; &#38;quot;delivery_problem_with_dog&#38;quot; }); 1
    SELECT me.child_id, me.stocking_address_id, me.name,
           delivery_problem_with_dog.child_id, delivery_problem_with_dog.tag,
           delivery_problem_with_dog.notes FROM child me
    LEFT JOIN reason delivery_problem_with_dog ON (
      delivery_problem_with_dog.child_id = me.child_id
      AND delivery_problem_with_dog.tag = ?
    )
    WHERE ( me.child_id = ? ):
         &#38;#39;dog&#38;#39;, &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;
    $res[1] = 1

    2&#38;gt; $child-&#38;gt;delivery_problem_with_dog &#38;amp;&#38;amp; &#38;quot;yes&#38;quot;
    $res[2] = &#38;#39;yes&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that the third line (labeled with &lt;code&gt;2&#38;gt;&lt;/code&gt;) doesn&#38;#39;t cause a second SQL query to be executed anymore.&lt;/p&gt;

&lt;h3 id=&#34;All-Done&#34;&gt;All Done&lt;/h3&gt;

&lt;p&gt;With those changes pushed to deployment (and the sysadmin elves no longer out for his blood) Chestnut Emberflakes could finally relax.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-22T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Quickly Building DBIx::Class Schemas</title><link href="http://perladvent.org/2017/2017-12-21.html"/><id>http://perladvent.org/2017/2017-12-21.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Chestnut Emberflakes had been put in charge of solving a &lt;b&gt;big&lt;/b&gt; problem at the North Pole. Several deliveries this year had failed to be delivered and he had to write a tool to store these few thousand orders in a database so Santa could make another quick orbit of the planet to re-deliver all those things he&#38;#39;d missed.&lt;/p&gt;

&lt;p&gt;Chestnut only had until the first orbit had been completed to build his tool. He didn&#38;#39;t have time to hand craft each and every SQL statement, but neither did he have time to write - and rewrite as he made changes - a bunch of class files for DBIx::Class so he could have it act as a ORM for him.&lt;/p&gt;

&lt;p&gt;The Wise Old Elf was very busy as always on Christmas Eve, but he had enough time to part some quick advice: &#38;quot;Let the code build the code for you&#38;quot;. Chestnut wasn&#38;#39;t sure what that meant, but he&#38;#39;d be sure to figure it out soon.&lt;/p&gt;

&lt;h3 id=&#34;What-Emberflakes-Had-To-Model&#34;&gt;What Emberflakes Had To Model&lt;/h3&gt;

&lt;p&gt;The requirements for the database model cold be summed up by this entity relationship diagram.&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src=&#34;erd.png&#34; width=&#34;600&#34; height=&#34;211&#34; alt=&#34;Entity Relationship Diagram&#34;&gt;&lt;/center&gt;

&lt;/p&gt;



&lt;p&gt;In short:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;Each child would receive one or more named presents&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Likewise each brand of present could be given to any number of children&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each child could have an address associated with them where the presents would be delivered (though some children sadly wouldn&#38;#39;t have an address and Santa would have to use some ingenuity there instead)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each address could have any number of children at it&lt;/p&gt;

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

&lt;h3 id=&#34;The-SQL&#34;&gt;The SQL&lt;/h3&gt;

&lt;p&gt;Chestnut quickly knocked up some SQL to create a Postgres database. This prototype didn&#38;#39;t have to be perfect - he wasn&#38;#39;t trying too hard to get all the types right in the most efficient manner, but just get this &lt;i&gt;done&lt;/i&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;synStatement&#34;&gt;DROP&lt;/span&gt; DATABASE &lt;span class=&#34;synSpecial&#34;&gt;IF&lt;/span&gt; &lt;span class=&#34;synStatement&#34;&gt;EXISTS&lt;/span&gt; prototype;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;CREATE&lt;/span&gt; DATABASE prototype;&lt;br /&gt;&lt;br /&gt;\c prototype;&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; stocking_address (&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;stocking_address_id UUID &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;street_address TEXT &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;lat &lt;span class=&#34;synType&#34;&gt;float&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;lon &lt;span class=&#34;synType&#34;&gt;float&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY stocking_address&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT stocking_address_pkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;PRIMARY KEY (stocking_address_id);&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; child (&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;child_id UUID &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;stocking_address_id UUID,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;name TEXT &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY child&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT child_pkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;PRIMARY KEY (child_id);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY child&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT child_stocking_address_id_fkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;FOREIGN KEY (stocking_address_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;REFERENCES  stocking_address(stocking_address_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;DEFERRABLE;&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; present (&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;present_id UUID &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;description TEXT &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY present&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT present_pkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;PRIMARY KEY (present_id);&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; child_presents (&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;child_id UUID &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;present_id UUID &lt;span class=&#34;synStatement&#34;&gt;NOT&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;NULL&lt;/span&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY child_presents&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT child_presents_pkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;PRIMARY KEY (child_id, present_id);&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY child_presents&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT child_idfkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;FOREIGN KEY (child_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;REFERENCES  child(child_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;DEFERRABLE;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;ALTER&lt;/span&gt; &lt;span class=&#34;synSpecial&#34;&gt;TABLE&lt;/span&gt; ONLY child_presents&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synSpecial&#34;&gt;ADD&lt;/span&gt; CONSTRAINT present_idfkey&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;FOREIGN KEY (present_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;REFERENCES  present(present_id)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;DEFERRABLE;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;He&#38;#39;d at least spent the time writing in the foreign key constraints. He didn&#38;#39;t have much time to spare, but he had even less time to spare debugging his database if he didn&#38;#39;t stop junk being put in their by mistake!&lt;/p&gt;

&lt;p&gt;Chestnut quickly setup the database on his dev machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ psql &#38;lt; database.sql
    DROP DATABASE
    CREATE DATABASE
    You are now connected to database &#38;quot;prototype&#38;quot; as user &#38;quot;Chestnut&#38;quot;.
    CREATE TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    ALTER TABLE
    ALTER TABLE&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Building-The-ORM-Classes-Automatically&#34;&gt;Building The ORM Classes Automatically&lt;/h3&gt;

&lt;p&gt;Emberflakes was just about to call out to see if anyone would help him when the Wise Old Elf snatched away his keyboard and typed something.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ dbicdump -o dump_directory=./lib \
        Prototype::Schema &#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And ran away. Emberflames was left staring at the message on his screen:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Dumping manual schema for Prototype::Schema to directory ./lib ...
    Schema dump completed.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What the huh? With no one to explain what had just happened Chestnut figured he better peek inside the &lt;code&gt;lib&lt;/code&gt; directory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ find .
    find .
    .
    ./lib
    ./lib/Prototype
    ./lib/Prototype/Schema
    ./lib/Prototype/Schema/Result
    ./lib/Prototype/Schema/Result/Child.pm
    ./lib/Prototype/Schema/Result/ChildPresent.pm
    ./lib/Prototype/Schema/Result/Present.pm
    ./lib/Prototype/Schema/Result/StockingAddress.pm
    ./lib/Prototype/Schema.pm&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ooooh. It&#38;#39;d all been written for him. Opening up one of the files shows all the code.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;utf8&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Prototype::Schema::Result::Child&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;# Created by DBIx::Class::Schema::Loader&lt;br /&gt;# DO NOT MODIFY THE FIRST PART OF THIS FILE&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;pod&#34;&gt;=head1 NAME&lt;br /&gt;&lt;br /&gt;Prototype::Schema::Result::Child&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&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;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;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;base&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;DBIx::Class::Core&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;pod&#34;&gt;=head1 TABLE: C&#38;lt;child&#38;gt;&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;child&#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;pod&#34;&gt;=head1 ACCESSORS&lt;br /&gt;&lt;br /&gt;=head2 child_id&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;data_type: &#39;uuid&#39;&lt;br /&gt;&#38;nbsp;&#38;nbsp;is_nullable: 0&lt;br /&gt;&#38;nbsp;&#38;nbsp;size: 16&lt;br /&gt;&lt;br /&gt;=head2 stocking_address_id&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;data_type: &#39;uuid&#39;&lt;br /&gt;&#38;nbsp;&#38;nbsp;is_foreign_key: 1&lt;br /&gt;&#38;nbsp;&#38;nbsp;is_nullable: 1&lt;br /&gt;&#38;nbsp;&#38;nbsp;size: 16&lt;br /&gt;&lt;br /&gt;=head2 name&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;data_type: &#39;text&#39;&lt;br /&gt;&#38;nbsp;&#38;nbsp;is_nullable: 0&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_columns&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;child_id&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;data_type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;uuid&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;is_nullable&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;span class=&#34;word&#34;&gt;size&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;16&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;double&#34;&gt;&#38;quot;stocking_address_id&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;data_type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;uuid&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;is_foreign_key&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;word&#34;&gt;is_nullable&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;word&#34;&gt;size&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;16&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;double&#34;&gt;&#38;quot;name&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;data_type&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;text&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;is_nullable&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;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;br /&gt;&lt;br /&gt;&lt;span class=&#34;pod&#34;&gt;=head1 PRIMARY KEY&lt;br /&gt;&lt;br /&gt;=over 4&lt;br /&gt;&lt;br /&gt;=item * L&#38;lt;/child_id&#38;gt;&lt;br /&gt;&lt;br /&gt;=back&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;set_primary_key&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;child_id&#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;pod&#34;&gt;=head1 RELATIONS&lt;br /&gt;&lt;br /&gt;=head2 child_presents&lt;br /&gt;&lt;br /&gt;Type: has_many&lt;br /&gt;&lt;br /&gt;Related object: L&#38;lt;Prototype::Schema::Result::ChildPresent&#38;gt;&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;has_many&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;child_presents&#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;double&#34;&gt;&#38;quot;Prototype::Schema::Result::ChildPresent&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;foreign.child_id&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;self.child_id&#38;quot;&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;word&#34;&gt;cascade_copy&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;span class=&#34;word&#34;&gt;cascade_delete&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;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;br /&gt;&lt;br /&gt;&lt;span class=&#34;pod&#34;&gt;=head2 stocking_address&lt;br /&gt;&lt;br /&gt;Type: belongs_to&lt;br /&gt;&lt;br /&gt;Related object: L&#38;lt;Prototype::Schema::Result::StockingAddress&#38;gt;&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;belongs_to&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;stocking_address&#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;double&#34;&gt;&#38;quot;Prototype::Schema::Result::StockingAddress&#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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;stocking_address_id&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;stocking_address_id&#38;quot;&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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;is_deferrable&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;join_type&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;LEFT&#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;word&#34;&gt;on_delete&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;NO ACTION&#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;word&#34;&gt;on_update&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;NO ACTION&#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;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;br /&gt;&lt;br /&gt;&lt;span class=&#34;pod&#34;&gt;=head2 presents&lt;br /&gt;&lt;br /&gt;Type: many_to_many&lt;br /&gt;&lt;br /&gt;Composing rels: L&#38;lt;/child_presents&#38;gt; -&#38;gt; present&lt;br /&gt;&lt;br /&gt;=cut&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;__PACKAGE__&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;many_to_many&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;presents&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;child_presents&#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;present&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# Created by DBIx::Class::Schema::Loader v0.07043 @ 2017-12-20 18:03:02&lt;br /&gt;# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:fvT7p0SmZa93Fop9i10jyA&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# You can replace this text with custom code or comments, and it will be preserved on regeneration&lt;br /&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;/pre&gt;

&lt;p&gt;There&#38;#39;s a lot to digest in that code. The important thing to remember was that no human (or elf) had to write any of it. And if any changes were made to the schema then it was possible to regenerate this file by simply re-running the command (regenerating the file won&#38;#39;t overwrite or lose any additional code any elf has added below the &lt;code&gt;DO NOT MODIFY THIS OR ANYTHING ABOVE LINE&lt;/code&gt;.)&lt;/p&gt;

&lt;h3 id=&#34;Loading-Test-Data&#34;&gt;Loading Test Data&lt;/h3&gt;

&lt;p&gt;Emberflakes decided that he&#38;#39;d better experiment with what was going on in the database, so he wrote a bunch of test data as JSON files to create some test fixtures.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    fixtures/StockingAddress.json:
    [
        {
            &#38;quot;stocking_address_id&#38;quot;: &#38;quot;db1e1ce1-bc05-4931-b79f-4356ea6270ff&#38;quot;,
            &#38;quot;street_address&#38;quot;: &#38;quot;671 Lincoln Ave. Winnetka, Illinois&#38;quot;,
            &#38;quot;lat&#38;quot;: -87.7358245,
            &#38;quot;lon&#38;quot;: 42.109756
        }
    ]

    fixtures/Present.json:
    [
        {
            &#38;quot;present_id&#38;quot;: &#38;quot;a9c15d33-b157-4513-9638-926d7793fdb1&#38;quot;,
            &#38;quot;description&#38;quot;: &#38;quot;BB Gun&#38;quot;
        },
        {
            &#38;quot;present_id&#38;quot;: &#38;quot;d321221e-6f1e-41ec-82b2-bda7d4783569&#38;quot;,
            &#38;quot;description&#38;quot;: &#38;quot;Micro Machines&#38;quot;
        },
        {
            &#38;quot;present_id&#38;quot;: &#38;quot;108bebb9-871b-45a6-b4e0-36fc720b2165&#38;quot;,
            &#38;quot;description&#38;quot;: &#38;quot;Blowtorch&#38;quot;
        }
    ]

    fixtures/Child.json:
    [
        {
            &#38;quot;child_id&#38;quot;: &#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;,
            &#38;quot;name&#38;quot;: &#38;quot;Kevin McCallister&#38;quot;,
            &#38;quot;stocking_address_id&#38;quot;: &#38;quot;db1e1ce1-bc05-4931-b79f-4356ea6270ff&#38;quot;,
            &#38;quot;child_presents&#38;quot;: [
                { &#38;quot;present_id&#38;quot;: &#38;quot;a9c15d33-b157-4513-9638-926d7793fdb1&#38;quot; },
                { &#38;quot;present_id&#38;quot;: &#38;quot;d321221e-6f1e-41ec-82b2-bda7d4783569&#38;quot; },
                { &#38;quot;present_id&#38;quot;: &#38;quot;108bebb9-871b-45a6-b4e0-36fc720b2165&#38;quot; }
            ]
        }
    ]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Reading these files in and using them to populate the database is fairly straight forward:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;#!/usr/bin/perl&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;version&#34;&gt;v5.22&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;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;lib&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(lib)&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;JSON::PP&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( decode_json )&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;Path::Tiny&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( path )&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;Prototype::Schema&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;# connect to the database&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Prototype::Schema&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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#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;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;txn_do&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;    # run with constraints disabled until the end of a transaction so we&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;# don&#39;t have to worry about the order in which we&#39;re inserting&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;# fixtures into the database&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;storage&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;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;SET CONSTRAINTS ALL DEFERRED&#39;&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;    # for each json file&lt;br /&gt;&lt;/span&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;grep&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/[.]json$/&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;fixtures&#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;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;&lt;span class=&#34;comment&#34;&gt;        # decode the json file&lt;br /&gt;&lt;/span&gt;        &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ds&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;decode_json&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&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;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;slurp&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;        # turn fixtures/Foo.json to Foo&lt;br /&gt;&lt;/span&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;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&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;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;basename&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;.json&#39;&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 result set&lt;br /&gt;&lt;/span&gt;        &lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rs&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&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;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;        # and insert each json object into the database&lt;br /&gt;&lt;/span&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;$row&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;$ds&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$rs&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;span class=&#34;symbol&#34;&gt;$row&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;/pre&gt;

&lt;p&gt;Since the database schema that Emberflakes had designed had &lt;code&gt;DEFERRABLE&lt;/code&gt; constraints it&#38;#39;s possible to use &lt;code&gt;SET CONSTRAINTS ALL DEFERRED&lt;/code&gt; to allow inserting incomplete foreign key data into the database, as long as when the transaction ends all the foreign keys are in place. If we didn&#38;#39;t do this&lt;/p&gt;

&lt;p&gt;There&#38;#39;s another thing worth noticing: Did you spot that there&#38;#39;s no &lt;code&gt;ChildPresent.json&lt;/code&gt; file? If you look closely at the &lt;code&gt;Child.json&lt;/code&gt; file you&#38;#39;ll notice that the &lt;code&gt;child_presents&lt;/code&gt; field isn&#38;#39;t actually a normal database field at all but the name of a DBIx::Class relationship - and DBIx::Class will take the array of objects that it contains and used them to create related objects for us.&lt;/p&gt;

&lt;h3 id=&#34;Playing-Around-with-the-data&#34;&gt;Playing Around with the data&lt;/h3&gt;

&lt;p&gt;More than anything Chestnut Emberflakes just needed to get to grips with the database schema. What better way to try it out than to use it interactively?&lt;/p&gt;

&lt;p&gt;Chestnut fired up the &lt;code&gt;reply&lt;/code&gt;, the Perl REPL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    bash$ reply -Ilib -MPrototype::Schema
    0&#38;gt; my $schema = Prototype::Schema-&#38;gt;connect(&#38;#39;dbi:Pg:dbname=prototype;host=127.0.0.1;port=5432&#38;#39;); 1
    $res[0] = 1

    1&#38;gt; my $child_rs = $schema-&#38;gt;resultset(&#38;#39;Child&#38;#39;); 1
    $res[1] = 1

    2&#38;gt; my $kevin = $child_rs-&#38;gt;find(&#38;quot;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;quot;); 1
    $res[2] = 1

    3&#38;gt; $kevin-&#38;gt;name;
    $res[3] = &#38;#39;Kevin McCallister&#38;#39;

    4&#38;gt; my $p = $kevin-&#38;gt;presents; 1
    $res[4] = 1

    5&#38;gt; $p-&#38;gt;next-&#38;gt;description;
    $res[5] = &#38;#39;BB Gun&#38;#39;

    6&#38;gt; $p-&#38;gt;next-&#38;gt;description;
    $res[6] = &#38;#39;Micro Machines&#38;#39;

    7&#38;gt; $p-&#38;gt;next-&#38;gt;description;
    $res[7] = &#38;#39;Blowtorch&#38;#39;

    8&#38;gt; $kevin-&#38;gt;name(&#38;#39;Kevin McCallister (aka Macaulay Culkin)&#38;#39;);
    $res[8] = &#38;#39;Kevin McCallister (aka Macaulay Culkin)&#38;#39;

    9&#38;gt; $kevin-&#38;gt;update; 1
    $res[9] = 1

    10&#38;gt; my $children = $child_rs-&#38;gt;search_rs( name =&#38;gt; &#38;#39;Kevin McCallister (aka Macaulay Culkin)&#38;#39; ); 1
    $res[10] = 1

    11&#38;gt; $children-&#38;gt;first-&#38;gt;child_id
    $res[11] = &#38;#39;f69eaf6c-bf77-4b29-9eca-78cda6fd2db7&#38;#39;

    12&#38;gt; $children-&#38;gt;first-&#38;gt;stocking_address-&#38;gt;street_address
    $res[12] = &#38;#39;671 Lincoln Ave. Winnetka, Illinois&#38;#39;

    14&#38;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that Chestnut was careful not to return any of the DBIx::Class objects (otherwise &lt;code&gt;reply&lt;/code&gt; would dump them out, which would be 300+ lines each of too much detail.)&lt;/p&gt;

&lt;h3 id=&#34;Not-Much-Coding-So-Much-Done&#34;&gt;Not Much Coding, So Much Done&lt;/h3&gt;

&lt;p&gt;With no actual Perl coding Chestnut Emberflakes had managed to get a fully functioning ORM setup where he could quickly prototype any task that the night might throw at him. Wish him luck...the children are counting on him.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-21T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Reindeer</title><link href="http://perladvent.org/2017/2017-12-20.html"/><id>http://perladvent.org/2017/2017-12-20.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;This year the Elves at the North Pole had learned a lot about powerful packages they could load to improve Moose. The problem was that things were getting a little on the long winded size at the top of each of their Moose-based packages...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ChristmasTree&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;Moose&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;MooseX::AttributeShortcuts&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;MooseX::AutoDestruct&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;MooseX::CascadeClearing&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;MooseX::ClassAttributes&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;MooseX::LazyRequire&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::StrictConstructor&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;MooseX::UndefTolerant::Attribute&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;/pre&gt;

&lt;p&gt;It was enough to make the Wise Old Elf&#38;#39;s RSI flair up once more. Something had to be done. It was time for something better than Moose.&lt;/p&gt;

&lt;p&gt;What&#38;#39;s better than Moose for one of Santa&#38;#39;s Elves? That&#38;#39;s right: &lt;a href=&#34;https://metacpan.org/module/Reindeer&#34;&gt;Reindeer&lt;/a&gt;. Still the same thing, but with more aerodynamic antlers.&lt;/p&gt;

&lt;p&gt;The Reindeer module from the CPAN is a wrapper for Moose that not only loads Moose into your class but loads a whole bunch of handy Moose extensions too. In fact, the above code could simply be replaced by:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ChristmasTree&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;Reindeer&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Does-All-The-Things&#34;&gt;Does All The Things&lt;/h3&gt;

&lt;p&gt;Reindeer does so much that it&#38;#39;s hard to document it all...&lt;/p&gt;

&lt;h4 id=&#34;All-our-Favourite-Extensions&#34;&gt;All our Favourite Extensions&lt;/h4&gt;

&lt;p&gt;Reindeer pulls in a bunch of modules that:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;Provide syntax for abstract methods&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable coercion by default (i.e. making it opt-out rather than opt-in)&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use shortcuts when writing attribute declarations&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provides currying for attribute delegation&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give you the ability to write class level attributes&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Throw exceptions if you try to read an un-set attribute&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offer better syntax for overriding default values for attributes in subclasses&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Throw exceptions if unknown parameters are passed to your constructor&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better construct anonymous classes with extra traits&lt;/p&gt;

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

&lt;h4 id=&#34;Type-Libraries&#34;&gt;Type Libraries&lt;/h4&gt;

&lt;p&gt;Reindeer exports a bunch of type libraries into your code. This means, for example, instead of writing your types as strings like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;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;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;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;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can write the same thing using a bunch of types like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;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;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;word&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &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;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;While these are just fancy no-argument function calls that return their own name (which are often inlined by the perl compiler) they act and feel like a real Perl syntax for types.&lt;/p&gt;

&lt;p&gt;Not only do you save those two characters, but by using function calls instead of strings, you also get all the advantages of &lt;code&gt;use strict&lt;/code&gt; to catch typos at compile time.&lt;/p&gt;

&lt;h4 id=&#34;Trait-Aliases&#34;&gt;Trait Aliases&lt;/h4&gt;

&lt;p&gt;Similarly Reindeer exports named traits (again, zero parameter functions, but actual implementations details aren&#38;#39;t important.) So instead of writing:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::Attribute::ENV&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;home&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;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;span class=&#34;word&#34;&gt;trait&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;ENV&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can write:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Reindeer&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;home&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;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;span class=&#34;word&#34;&gt;trait&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;ENV&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As well as providing the slight reduction in typing, better typo checking, this also provides lazy loading of the trait classes - the first time the named trait is used the trait class will be loaded (this means there&#38;#39;s no penalty for having the traits available if you don&#38;#39;t use them.)&lt;/p&gt;

&lt;h4 id=&#34;Extra-Language-Features-and-Extensions&#34;&gt;Extra Language Features and Extensions&lt;/h4&gt;

&lt;p&gt;Reindeer also enables a bunch non-Moose extra things that are either optional in Perl, or are standard extensions.&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;p&gt;Enables all features for the version of Perl you&#38;#39;re running. For example, if you&#38;#39;re running 5.10 or later then you&#38;#39;ll be able to use the &lt;code&gt;say&lt;/code&gt; keyword.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provides &lt;code&gt;try&lt;/code&gt;, &lt;code&gt;catch&lt;/code&gt; and &lt;code&gt;finally&lt;/code&gt; from &lt;a href=&#34;https://metacpan.org/module/Try::Tiny&#34;&gt;Try::Tiny&lt;/a&gt; to give you handy &lt;code&gt;try { ...}&lt;/code&gt; blocks.&lt;/p&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleans your namespace with &lt;a href=&#34;https://metacpan.org/module/namespace::autoclean&#34;&gt;namespace::autoclean&lt;/a&gt; so utility functions you import aren&#38;#39;t callable as methods&lt;/p&gt;

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

&lt;h3 id=&#34;Less-Typing-Is-Less-Mistakes&#34;&gt;Less Typing Is Less Mistakes&lt;/h3&gt;

&lt;p&gt;The Wise Old Elf was happy. He was well aware that a large amount of the code written by the Elves was written in the last few weeks before Christmas in a big rush. Not only would Reindeer act as a force multiplier for his development team making their work quicker, it would also reduce the amount of code they&#38;#39;d have to write, and hopefully therefore the number of chances to introduce bugs.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-20T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Maybe not</title><link href="http://perladvent.org/2017/2017-12-19.html"/><id>http://perladvent.org/2017/2017-12-19.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;&#38;quot;What&#38;#39;s this &lt;code&gt;Maybe&lt;/code&gt; here for?&#38;quot; asked the Wise Old Elf. He was looking at the new Moose code that Syllabub Fizzyboughs had written for the new and improved Sleigh operating system.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;gps_unit&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;isa&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Maybe&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;GPSUnit&#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;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;You see, Wise Old Elf, the &lt;code&gt;Maybe&lt;/code&gt; says that the value can either be whatever is in the brackets or can be &lt;code&gt;undef&lt;/code&gt;. So this means the value has to be something that&#38;#39;s a GPS unit or undef - in case there&#38;#39;s no GPS unit attached, you see.&#38;quot;, Syllabub explained.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$basic_sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk I&#39;&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;# prints nothing!&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$basic_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;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;core&#34;&gt;defined&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$basic_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;$fancy_sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk II&#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;gps_unit&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;GPSUnit&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Super GPS 2001&#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;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# prints &#39;Super GPS 2001&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$fancy_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;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;core&#34;&gt;defined&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$fancy_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Yes, yes. I know what &lt;code&gt;Maybe&lt;/code&gt; &lt;b&gt;does&lt;/b&gt;. But I asked &lt;b&gt;what&lt;/b&gt; it&#38;#39;s there for. Haven&#38;#39;t you heard the expression &#38;#39;Maybe is a code smell?&#38;#39;&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;No Wise Old Elf, can&#38;#39;t say that I have. To be honest, I&#38;#39;m not sure what you mean by code smell. My keyboard smells of freshly baked cookies like any other workstation at the North Pole.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;A code smell, by young elf, is a pattern that indicates that probably there&#38;#39;s something wrong with your code. Other people call them &#38;#39;Red Flags&#38;#39;. In this case it&#38;#39;s because nine times out of ten, if you&#38;#39;re using a &lt;code&gt;Maybe&lt;/code&gt; you&#38;#39;re better off using a predicate&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;gps_unit&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;isa&lt;/span&gt;       &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;GPSUnit&#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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;predicate&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;has_gps_unit&#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;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Or, if you&#38;#39;re using &lt;a href=&#34;https://metacpan.org/module/MooseX::AttributeShortcuts&#34;&gt;MooseX::AttributeShortcuts&lt;/a&gt;&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;gps_unit&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;isa&lt;/span&gt;       &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;GPSUnit&#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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;predicate&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;/pre&gt;

&lt;p&gt;&#38;quot;So now you can use the &lt;code&gt;has_gps_unit&lt;/code&gt; method&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# prints &#39;Super GPS 2001&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$fancy_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;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;core&#34;&gt;defined&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$fancy_sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;has_gps_unit&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;MooseX::LazyRequire&#34;&gt;MooseX::LazyRequire&lt;/h3&gt;

&lt;p&gt;&#38;quot;Okay&#38;quot;, Syllabub asked, &#38;quot;why would I want to do that?&#38;quot;&lt;/p&gt;

&lt;p&gt;The Wise Old Elf explained, for starters, it&#38;#39;s a lot more readable with exactly what&#38;#39;s going on when you use the &lt;code&gt;has_gps_unit&lt;/code&gt; method. But what really blew Syllabub&#38;#39;s mind was when the Wise Old Elf showed him &lt;a href=&#34;https://metacpan.org/module/MooseX::LazyRequires&#34;&gt;MooseX::LazyRequires&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even with a predicate you can still read from an attribute that hasn&#38;#39;t been set in the constructor, and you&#38;#39;ll get &lt;code&gt;undef&lt;/code&gt; back. This can result in hard to debug problems, where the value is taken, passed somewhere else, then much later in your code when something tries to access it...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# in Sleigh&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;fly_to_destination&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$place&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;&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;$trip&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Trip&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;start&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;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;current_location&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;end&lt;/span&gt;   &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$place&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;gps&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;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$trip&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;route&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;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This leads to the really unreadable error message from deep within the &lt;code&gt;Trip&lt;/code&gt; class&#38;#39;s &lt;code&gt;route&lt;/code&gt; method if the &lt;code&gt;gps_unit&lt;/code&gt; attribute isn&#38;#39;t set and returns &lt;code&gt;undef&lt;/code&gt; when &lt;code&gt;fly_to_destination&lt;/code&gt; is called. What you really need to do is throw an exception as soon as you try reading from an accessor that isn&#38;#39;t set. That&#38;#39;s what MooseX::LazyRequires does for any attribute that has the &lt;code&gt;lazy_requires&lt;/code&gt; parameter enabled:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::LazyRequire&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;gps_unit&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;predicate&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;lazy_required&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;/pre&gt;

&lt;p&gt;Which now, if you don&#38;#39;t set the &lt;code&gt;gps_unit&lt;/code&gt; prior to calling &lt;code&gt;fly_to_destination&lt;/code&gt;, &lt;b&gt;immediately&lt;/b&gt; generates a much more readable error message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Attribute &#38;#39;gps_unit&#38;#39; must be provided before calling reader
        at /opt/perl/lib/site_perl/5.22.0/MooseX/LazyRequire/Meta/Attribute/Trait/LazyRequire.pm line 34.
        MooseX::LazyRequire::Meta::Attribute::Trait::LazyRequire::__ANON__(Sleigh=HASH(0x7fd3a1807908))
           called at reader Sleigh::gps_unit (defined at Sleigh.pm line 7) line 6
        Sleigh::gps_unit(Sleigh=HASH(0x7fd3a1807908))
           called at Sleigh.pm line 18
        Sleigh::fly_to_destination(Sleigh=HASH(0x7fd3a1807908))
           called at example.pl line 6&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Syllabub was convinced and made the changes to all of his code.&lt;/p&gt;

&lt;h3 id=&#34;MooseX::UndefTolerant::Attribute&#34;&gt;MooseX::UndefTolerant::Attribute&lt;/h3&gt;

&lt;p&gt;&#38;quot;Wise Old Elf, I&#38;#39;ve got a problem&#38;quot;, Syllabub explained the next day, &#38;quot;I changed all my code and now it&#38;#39;s broken wherever I pass in &lt;code&gt;undef&lt;/code&gt;&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk III&#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;gps_unit&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$factory&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# might return undef if there isn&#39;t one&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;We do this all over the place. Do I have to change all my code?&#38;quot;. Syllabub showed the Wise Old Elf what he&#38;#39;d been &#38;quot;&lt;i&gt;forced&lt;/i&gt;&#38;quot; to write:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gps&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$factory&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&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;symbol&#34;&gt;$gps&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;symbol&#34;&gt;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk III&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;gps_unit&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gps&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;keyword&#34;&gt;else&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;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk III&#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;/pre&gt;

&lt;p&gt;The Wise Old Elf explained that he could probably make his life a lot easier with the ternary operator:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gps&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$factory&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gps_unit&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;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk III&#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;symbol&#34;&gt;$gps&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;word&#34;&gt;gps_unit&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gps&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;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;/pre&gt;

&lt;p&gt;But there was another simpler strategy: Use &lt;a href=&#34;https://metacpan.org/module/MooseX::UndefTolerant::Attribute&#34;&gt;MooseX::UndefTolerant::Attribute&lt;/a&gt; to allow &lt;code&gt;undef&lt;/code&gt; to mean the same thing as &lt;i&gt;we didn&#38;#39;t pass a value&lt;/i&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::UndefTolerant::Attribute&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;gps_unit&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;traits&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;UndefTolerant&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;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;predicate&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;lazy_required&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;operator&#34;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;# this now works fine, as if gps_unit hadn&#39;t been passed&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Sleigh&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Mk IV&#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;gps_unit&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;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;br /&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Cleaner-Code-All-Round&#34;&gt;Cleaner Code All Round&lt;/h3&gt;

&lt;p&gt;Syllabub was happy. His code was a lot easier to debug, and he&#38;#39;d learned something from the Wise Old Elf. Code review might be painful, but everything was a lot better afterward.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-19T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Project Multipli-sleigh-ion</title><link href="http://perladvent.org/2017/2017-12-18.html"/><id>http://perladvent.org/2017/2017-12-18.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Project Multipli-sleigh-ion was the last, great hope for the North Pole to cope with the ever increasing child population. More children equaled more presents that had to be loaded on the sleigh and it was getting out of hand. Multipli-sleigh-ion was going to address this by replacing the vertical scaling - ever more powerful magic to fit everything in one sack - with horizontal scaling - lots of sacks of presents stashed at strategic locations around the globe for Santa to pick up en-route.&lt;/p&gt;

&lt;p&gt;Rustic Starpie had been put in charge of writing modeling code to test the feasibility of this approach. In his model code each class of present consumed one common role &lt;code&gt;Present&lt;/code&gt;, and in doing so was required to implement the &lt;code&gt;ideal_sack&lt;/code&gt; method.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Present&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::Role&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;requires&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ideal_sack&#39;&lt;/span&gt;&lt;span class=&#34;operator&#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;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;put_in_sack&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@sacks&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;ideal_sack&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@sacks&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;unless&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$ideal_sack&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;full&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;$ideal_sack&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_present&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;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;&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;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Modeling failed, can&#39;t fit &#38;quot;&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;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;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;&lt;span class=&#34;single&#34;&gt;&#39; into sack &#39;&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;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;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;/pre&gt;

&lt;p&gt;The &lt;code&gt;ideal_sack&lt;/code&gt; code was implemented differently in each class that consumed the &lt;code&gt;Present&lt;/code&gt; role, but each implementation ultimately decided which of the passed sack objects it should put itself in. For example, the figgy puddings were for the English children, so they always went into the English sack&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;FiggyPuddingPresent&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;Moose&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Present&#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;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;sub&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;single&#34;&gt;&#39;Figgy Pudding&#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;ideal_sack&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@sacks&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;name&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;London, UK&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@sacks&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;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;/pre&gt;

&lt;p&gt;The problem Rustic was having with his code is that, well, it wasn&#38;#39;t always doing what it was supposed to in all cases. So he decided to add some debugging in the Present role to print out which sack everything was going to go into.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Present&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::Role&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;requires&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ideal_sack&#39;&lt;/span&gt;&lt;span class=&#34;operator&#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;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;around&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ideal_sack&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;$orig&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;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;&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;$ideal_sack&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;symbol&#34;&gt;$orig&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;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;heredoc&#34;&gt;&#38;lt;&#38;lt;~&#38;quot;OUT&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;    The ideal sack for a @{[ $self-&#38;gt;name ]} is @{[ $ideal_sack-&#38;gt;name ]}&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;    OUT&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;/pre&gt;

&lt;p&gt;This code would cause any &lt;code&gt;ideal_sack&lt;/code&gt; method to be wrapped in code that produced output of the form:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    The ideal sack for a Figgy Pudding is London, UK
    The ideal sack for a Chocolate Coin is Paris, France
    The ideal sack for a Chocolate Coin is Moscow, Russia
    The ideal sack for a Figgy Pudding is London, UK
    The ideal sack for a Chocolate Coin is London, UK
    The ideal sack for a Chocolate Coin is New York, USA
    The ideal sack for a Figgy Pudding is London, UK
    Can&#38;#39;t fit Figgy Pudding into sack London, UK at line 16 of Present.pm.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(The chocolate coins are distributed randomly between sacks)&lt;/p&gt;

&lt;p&gt;This was &lt;i&gt;somewhat&lt;/i&gt; helpful, it really isn&#38;#39;t what Rustic wanted. He wanted to know how many Figgy Puddings he&#38;#39;d successfully managed to put into the sack, and he really didn&#38;#39;t want to have to count the lines of his debug output. He wanted output of the form:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    The ideal sack for the 3214th Figgy Pudding is London, UK
    The ideal sack for the 91231st Chocolate Coin is Paris, France
    The ideal sack for the 91232nd Chocolate Coin is Moscow, Russia
    The ideal sack for the 3215th Figgy Pudding is London, UK
    The ideal sack for the 91233rd Chocolate Coin is London, UK
    The ideal sack for the 91234th Chocolate Coin is New York, USA
    The ideal sack for the 3216th Figgy Pudding is London, UK
    Can&#38;#39;t fit Figgy Pudding into sack London, UK at line 16 of Present.pm.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How could Rustic get Perl to keep track of the number of times &lt;code&gt;ideal_sack&lt;/code&gt; had been called per class? The data can&#38;#39;t be stored in the instances because they&#38;#39;re distrinct from one another. What Rustic needed was some sort of class level storage.&lt;/p&gt;

&lt;p&gt;Luckily, there&#38;#39;s a module for that. &lt;a href=&#34;https://metacpan.org/module/MooseX::ClassAttribute&#34;&gt;MooseX::ClassAttribute&lt;/a&gt; provides a new keyword &lt;code&gt;class_has&lt;/code&gt; that defines an attribute shared at the &lt;i&gt;class&lt;/i&gt; level rather than the &lt;i&gt;instance&lt;/i&gt; level. All objects of the same class share the same value:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Present&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::Role&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;MooseX::ClassAttribute&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;Lingua::EN::Numbers::Ordinate&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;ordinate&#39;&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;requires&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ideal_sack&#39;&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;class_has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_packed_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;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;around&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ideal_sack&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;$orig&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;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;&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;$ideal_sack&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;symbol&#34;&gt;$orig&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;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;$counter&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;_packed_counter&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;_packed_counter&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#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;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;$c&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$counter&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;print&lt;/span&gt; &lt;span class=&#34;heredoc&#34;&gt;&#38;lt;&#38;lt;~&#38;quot;OUT&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;    The ideal sack for the $c @{[ $self-&#38;gt;name ]} is @{[ $ideal_sack-&#38;gt;name ]}&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;    OUT&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;/pre&gt;

&lt;p&gt;We have the full power of Moose attributes behind the class attributes. For example, Rustic could rewrite the above to be clearer with the &lt;a href=&#34;https://metacpan.org/module/Moose::Meta::Attribute::Native::Trait::Counter&#34;&gt;Moose::Meta::Attribute::Native::Trait::Counter&lt;/a&gt; trait to handle incrementing the counter.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Present&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::Role&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;MooseX::ClassAttribute&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;Lingua::EN::Numbers::Ordinate&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;ordinate&#39;&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;requires&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;ideal_sack&#39;&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;class_has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_packed_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;traits&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;Counter&#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;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;handles&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;word&#34;&gt;_increment_packed_counter&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;inc&#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;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;around&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ideal_sack&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;$orig&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;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;&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;$ideal_sack&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;symbol&#34;&gt;$orig&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;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;_increment_packed_counter&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;$c&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&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;_packed_counter&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;print&lt;/span&gt; &lt;span class=&#34;heredoc&#34;&gt;&#38;lt;&#38;lt;~&#38;quot;OUT&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;    The ideal sack for the $c @{[ $self-&#38;gt;name ]} is @{[ $ideal_sack-&#38;gt;name ]}&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;    OUT&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ideal_sack&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;/pre&gt;

&lt;p&gt;With the new debugging output Rustic was quickly able to determine where the problems were in the code in time for his project review with the Wise Old Elf.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-18T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Making a constructor argument list, checking it twice.</title><link href="http://perladvent.org/2017/2017-12-17.html"/><id>http://perladvent.org/2017/2017-12-17.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;&#38;quot;Wise Old Elf, Wise Old Elf&#38;quot;, Licorice Stripysparkles called out, &#38;quot;I think your code is broken.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Broken, you say, Licorice? That&#38;#39;s odd, it passes all its tests.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Yeah, Wise Old Elf, I know that. But look, when I try setting the lead reindeer to Robbie, Rudolph&#38;#39;s son, when I&#38;#39;m constructing the Sleigh, it just doesn&#38;#39;t work! It keeps using the default from the lazy builder, giving me back Rudolph each time.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Nonsense, young one. There&#38;#39;s a test for that. Are you sure that &lt;code&gt;_build_lead_reindeer&lt;/code&gt; is being erroneously called?&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Yep, I put some debug code in it to print out to STDERR, and by jove, it&#38;#39;s being called each and every time, if I pass a value for &lt;code&gt;lead_reindeer&lt;/code&gt; to the constructor or not.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Most odd. Show me exactly what you&#38;#39;re doing.&#38;quot;&lt;/p&gt;

&lt;p&gt;Stripysparkles opened up his editor and showed the Wise Old Elf his code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# create the test sleigh&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sleigh&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;SantasSleigh&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;lead_raindeer&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Robbie&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;,&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;say&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ref&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sleigh&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;lead_reindeer&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Licorice, my boy, that&#38;#39;s &lt;i&gt;not&lt;/i&gt; how you spell reindeer. R-E-I-N not R-A-I-N!&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Oops, sorry Wise Old Elf, My Bad!&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;No, Licorice, I don&#38;#39;t really think it is your &lt;i&gt;bad&lt;/i&gt;. If it&#38;#39;s anyone&#38;#39;s &lt;i&gt;bad&lt;/i&gt; it&#38;#39;s mine.&#38;quot;&lt;/p&gt;

&lt;h3 id=&#34;Not-Strict-Enough&#34;&gt;Not Strict Enough&lt;/h3&gt;

&lt;p&gt;By default Moose lets you pass any argument you want to the constructor method. If it doesn&#38;#39;t have a corresponding attribute for that parameter Moose happily ignores the parameter.&lt;/p&gt;

&lt;p&gt;This can, as Licorice Stripysparkles had discovered, often lead to some hard to diagnose bugs. The solution is to throw an exception if someone passes you a duff argument.&lt;/p&gt;

&lt;p&gt;Now, we could write some complex code in a &lt;code&gt;BUILDARGS&lt;/code&gt; method that checked the arguments. But it would be fragile, and we would have to keep updating it when our class (or superclasses, or roles) added new attributes. Why don&#38;#39;t we instead take advantage of Moose to do some introspection on the object and work this out dynamically for us? Better yet, we could use a reusable class trait (a role for the class&#38;#39;s metaclass) that does all of this for us without having to actually write any code for our particular class.&lt;/p&gt;

&lt;p&gt;This is exactly what the CPAN module &lt;a href=&#34;https://metacpan.org/module/MooseX::StrictConstructor&#34;&gt;MooseX::StrictConstructor&lt;/a&gt; does. Loading this class in your Moose class monkeys around with the metaclass for the class you&#38;#39;re writing in order to add strict constructor checks. So once the Wise Old Elf changed the code to include one extra use statement...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;SantasSleigh&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;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::StrictConstructor&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It meant that when Licorice ran his broken code he got an actual helpful error message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Found unknown attribute(s) init_arg passed to the constructor: lead_raindeer&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;</summary><updated>2017-12-17T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>For Elves, Shorter is Better</title><link href="http://perladvent.org/2017/2017-12-16.html"/><id>http://perladvent.org/2017/2017-12-16.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;One of the problems in being the Wise Old Elf was, well, the &lt;i&gt;old&lt;/i&gt; part. The Wise Old Elf had been typing for so many years - rushing every Christmas - that he&#38;#39;d developed a case of RSI that flared up at the most inconvenient times.&lt;/p&gt;

&lt;p&gt;As such, he was always looking for ways to avoid typing so much, and this Christmas, he thought he&#38;#39;d found one.&lt;/p&gt;

&lt;h3 id=&#34;Verbose.-Verbosity.-So-long-winded.-On-and-On&#34;&gt;Verbose. Verbosity. So long winded. On and On.&lt;/h3&gt;

&lt;p&gt;One of the problems with Moose in its default configuration is that it can be, well, a little wordy...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;lead_reindeer&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;isa&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;br /&gt;&#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;&lt;span class=&#34;word&#34;&gt;builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_build_lead_reindeer&#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;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;second_reindeer&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;isa&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;br /&gt;&#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;&lt;span class=&#34;word&#34;&gt;builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_build_second_reindeer&#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;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;third_reindeer&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;isa&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;br /&gt;&#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;&lt;span class=&#34;word&#34;&gt;builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_build_third_reindeer&#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;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;forth_reindeer&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;isa&lt;/span&gt;     &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;br /&gt;&#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;&lt;span class=&#34;word&#34;&gt;builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_build_forth_reindeer&#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;operator&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# and on and on for another five reindeer!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Putting aside the fact that this is probably better written using some sort of array data structure (which is literally an article for another day) what can be done to make this less verbose?&lt;/p&gt;

&lt;h3 id=&#34;Enter-MooseX::AttributeShortcuts&#34;&gt;Enter MooseX::AttributeShortcuts&lt;/h3&gt;

&lt;p&gt;Why, yes, we can make this much shorter, with the help of the &lt;a href=&#34;https://metacpan.org/module/MooseX::AttributeShortcuts&#34;&gt;MooseX::AttributeShortcuts&lt;/a&gt; CPAN module:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MooseX::AttributeShortcuts&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;structure&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;words&#34;&gt;qw(&lt;br /&gt;&#38;nbsp;&#38;nbsp;lead_reindeer second_reindeer third_reindeer forth_reindeer&lt;br /&gt;&#38;nbsp;&#38;nbsp;fifth_reindeer sixth_reindeer seveth_reindeer eighth_reindeer&lt;br /&gt;)&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;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;isa_instance_of&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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&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;&lt;span class=&#34;word&#34;&gt;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;/code&gt;&lt;/pre&gt;

&lt;p&gt;Loading MooseX::AttributeShortcuts into your Moose class enables a whole bunch of extra parameter handing for &lt;code&gt;has&lt;/code&gt; that provides shortcuts to make writing attribute code simpler. In the above example we see two such shortcuts: The first shortcut, writing &lt;code&gt;isa_instance_of =&#38;gt; &#38;#39;SantasReindeer&#38;#39;&lt;/code&gt; instead of &lt;code&gt;isa =&#38;gt; class_type(&#38;#39;SantasReindeer&#38;#39;)&lt;/code&gt; provides us a little win, the biggest reduction in code comes from &lt;code&gt;builder =&#38;gt; 1&lt;/code&gt;. By setting the builder to a plain old &lt;code&gt;1&lt;/code&gt; we&#38;#39;re letting MooseX::AttributeShortcuts tell Moose that we want to use the default name for our builder - whatever the accessor is called with &lt;code&gt;_build_&lt;/code&gt; prepended to it. And because now we don&#38;#39;t need a custom builder parameter for each attribute, we can declare all nine in a single &lt;code&gt;has&lt;/code&gt; declaration!&lt;/p&gt;

&lt;p&gt;Can we make this shorter still? Yep! We can just say, like with &lt;a href=&#34;https://metacpan.org/module/Moo&#34;&gt;Moo&lt;/a&gt;, that this is &lt;code&gt;lazy&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;words&#34;&gt;qw(&lt;br /&gt;&#38;nbsp;&#38;nbsp;lead_reindeer second_reindeer third_reindeer forth_reindeer&lt;br /&gt;&#38;nbsp;&#38;nbsp;fifth_reindeer sixth_reindeer seveth_reindeer eighth_reindeer&lt;br /&gt;)&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;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;lazy&#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;isa_instance_of&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;/code&gt;&lt;/pre&gt;

&lt;p&gt;That shortcut create a read only accessor that is lazy and uses the default Moose accessor.&lt;/p&gt;

&lt;p&gt;In addition to &lt;code&gt;lazy&lt;/code&gt;, MooseX::AttributeShortcuts also accepts &lt;code&gt;is =&#38;gt; &#38;#39;rwp&#38;#39;&lt;/code&gt;. &lt;code&gt;rwp&lt;/code&gt; creates a public reader accessor of the form &lt;code&gt;foo&lt;/code&gt; and a private writer accessor of the form &lt;code&gt;_set_foo&lt;/code&gt; (since by convention in Perl methods starting with an underscore are private and shouldn&#38;#39;t be called from outside of the class.)&lt;/p&gt;

&lt;h3 id=&#34;Custom-Anonymous-Types&#34;&gt;Custom Anonymous Types&lt;/h3&gt;

&lt;p&gt;It would be nice to make sure that the lead reindeer has a glowing nose, but that would probably involve a custom type class to check the value&#38;#39;s &lt;code&gt;glowing_nose&lt;/code&gt; attribute:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NorthPole::Types&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;MooseX::Types&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;-declare&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;words&#34;&gt;qw(&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;SantasReindeerWithAGlowingNose&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;)&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;subtype&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;SantasReindeerWithAGlowingNose&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;as&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;class_type&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;where&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;inline_as&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;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;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;parent&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;_inline_check&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;number&#34;&gt;1&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;double&#34;&gt;&#38;quot; &#38;amp;&#38;amp; $_[1]-&#38;gt;glowing_nose&#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;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then use that new type:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NorthPole::Types&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( SantasReindeerWithAGlowingNose )&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;lead_reindeer&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;lazy&#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;isa&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;SantasReindeerWithAGlowingNose&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;/pre&gt;

&lt;p&gt;That is a &lt;b&gt;lot&lt;/b&gt; of typing if you&#38;#39;re only going to use it in one place. How about we use another shortcut?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;lead_reindeer&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;lazy&#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;isa&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;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;blessed&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;amp;&#38;amp;&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;isa&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;&#38;amp;&#38;amp;&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;glowing_nose&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;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;/pre&gt;

&lt;p&gt;Here we&#38;#39;re quickly defining a new one off type &lt;i&gt;inline&lt;/i&gt;! It&#38;#39;s not the most readable thing in the world though, is it? MooseX::AttributeShortcuts allows us to specify this in a more straight forward manner by allowing an inline &lt;i&gt;constraint&lt;/i&gt;, which is an additional condition that will be checked for truthfulness after the &lt;code&gt;isa&lt;/code&gt; / &lt;code&gt;isa_instance_of&lt;/code&gt; check has occurred.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;lead_reindeer&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;lazy&#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;isa_instance_of&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#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;constraint&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;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;glowing_nose&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;/pre&gt;

&lt;p&gt;As an added benefit writing a &lt;code&gt;constraint&lt;/code&gt; / &lt;code&gt;isa&lt;/code&gt; pair is that this subtypes the original type, meaning that coercions associated with the original type will just work!&lt;/p&gt;

&lt;h3 id=&#34;Much-much-more&#34;&gt;Much much more&lt;/h3&gt;

&lt;p&gt;The Wise Old Elf continued to read the documentation for MooseX::AttributeShortcuts finding out about all sorts of things, from easy trigger, clearer and predicate declaration through quickly defining inline coercions and builder methods. He, like you should, was going to spend a good afternoon playing with this module - not only to avoid so much typing, but also to avoid writing so much boilerplate code and reduce the potential for bugs.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-16T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Mojolicious on the Command Line</title><link href="http://perladvent.org/2017/2017-12-15.html"/><id>http://perladvent.org/2017/2017-12-15.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Mojolicious provides a utility class, &lt;a href=&#34;https://metacpan.org/module/ojo&#34;&gt;ojo&lt;/a&gt;, that allows us to leverage the power of Mojolicious from the command line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    perl -Mojo -E &#38;#39;say g(&#38;quot;http://goo.gl/EsGk3b&#38;quot;)-&#38;gt;text&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-M&lt;/code&gt; flag tells perl to load the following module, so &lt;code&gt;-Mojo&lt;/code&gt;, despite looking like a super secret Mojo flag to perl actually is a cheeky way of saying &lt;code&gt;use ojo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ojo&lt;/code&gt; provides a whole host of single letter functions that are shortcuts to Mojolicious utilities, allowing you to quickly do things like fetching urls, reading and writing files, encoding and decoding json, manipulating data structures and a whole host more.&lt;/p&gt;

&lt;h3 id=&#34;A-Worked-Example&#34;&gt;A Worked Example&lt;/h3&gt;

&lt;p&gt;Since the things you can do with &lt;code&gt;ojo&lt;/code&gt; are virtually limitless, I thought a good intro to &lt;code&gt;ojo&lt;/code&gt; might be to show a worked example from the command line.&lt;/p&gt;

&lt;p&gt;I like reading the Perl Weekly, the weekly Perl email newsletter that pops into my inbox every week. It&#38;#39;s so good that I often find myself wanting to refer back to a linked article later in the week when the email has been buried deep in my ever increasing inbox. Rather than improving my email filing (I&#38;#39;ll get around to that one day) I instead wrote a script to grab an archived copy of the email from the Perl Weekly website and print out all the links. How did I do that?&lt;/p&gt;

&lt;p&gt;So, let&#38;#39;s start by having &lt;code&gt;ojo&lt;/code&gt; fetch the archive and print it out&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;ojo&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;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;http://perlweekly.com/archive/333.html&#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;text&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;g&lt;/code&gt; function creates a GET request, returning a &lt;a href=&#34;https://metacpan.org/module/Mojo::Message::Response&#34;&gt;Mojo::Message::Response&lt;/a&gt; object (which inherits a whole load of useful )&lt;/p&gt;

&lt;p&gt;Printing the results of the &lt;code&gt;text&lt;/code&gt; method output the entire HTML of the newsletter, of which the bit we&#38;#39;re interested in looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &#38;lt;div class=&#38;quot;entry-title&#38;quot;&#38;gt;
                &#38;lt;a href=&#38;quot;http://perladvent.org/2017/index.html&#38;quot; style=&#38;quot;
                   font-size: 18px;
                   font-weight: bold;
                   &#38;quot;&#38;gt;Perl Advent Calendar&#38;lt;/a&#38;gt;
              &#38;lt;/div&#38;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So we can adapt our &lt;code&gt;ojo&lt;/code&gt; script to use the &lt;code&gt;dom&lt;/code&gt; method to pull out just these sections using a CSS selector:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;http://perlweekly.com/archive/333.html&#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;&#38;nbsp;&#38;nbsp;&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;double&#34;&gt;&#38;quot;.entry-title a&#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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;\n\n&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;dom&lt;/code&gt; method returns a &lt;a href=&#34;https://metacpan.org/module/Mojo::Collection&#34;&gt;Mojo::Collection&lt;/a&gt; - Mojolicious&#38;#39;s super smart array wrapper - on which we can call methods. Here we&#38;#39;re just joining them together (and stringifying the objects that &lt;code&gt;dom&lt;/code&gt; returned) so we can check we got the right stuff. The output now looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &#38;lt;a href=&#38;quot;http://perladvent.org/2017/index.html&#38;quot; style=&#38;quot;
                        font-size: 18px;
                        font-weight: bold;
                        &#38;quot;&#38;gt;Perl Advent Calendar&#38;lt;/a&#38;gt;

    &#38;lt;a href=&#38;quot;https://perl6advent.wordpress.com/&#38;quot; style=&#38;quot;
                        font-size: 18px;
                        font-weight: bold;
                        &#38;quot;&#38;gt;Perl 6 Advent Calendar&#38;lt;/a&#38;gt;

    &#38;lt;a href=&#38;quot;https://mojolicious.io/blog/&#38;quot; style=&#38;quot;
                        font-size: 18px;
                        font-weight: bold;
                        &#38;quot;&#38;gt;Mojolicious Advent Calendar&#38;lt;/a&#38;gt;
    (etc)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Okay, we now want to break apart the &lt;a href=&#34;https://metacpan.org/module/Mojo::DOM&#34;&gt;Mojo::DOM&lt;/a&gt; objects that &lt;code&gt;dom&lt;/code&gt; returned to get the href and text of the link. To do this we use the &lt;code&gt;map&lt;/code&gt; method on the collection that will call a subroutine on each element of the collection (similar to Perl&#38;#39;s &lt;code&gt;map&lt;/code&gt; keyword on arrays)&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;http://perlweekly.com/archive/333.html&#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;&#38;nbsp;&#38;nbsp;&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;double&#34;&gt;&#38;quot;.entry-title a&#38;quot;&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;map&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;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;attr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;href&#38;quot;&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;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;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\n&#38;quot;&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;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;join&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Calling &lt;code&gt;join&lt;/code&gt; with no arguments joins the elements with the empty string. The output is much much closer to what we want:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    https://perl6advent.wordpress.com/: Perl 6 Advent Calendar
    https://mojolicious.io/blog/: Mojolicious Advent Calendar
    http://www.lenjaffe.com/AdventPlanet/2017/: Advent Planet 2017
    http://blogs.perl.org/users/mohammad_s_anwar/2017/12/london-perl-workshop-2017---talks-review.html: London Perl Workshop 2017 - Talks Review
    http://blogs.perl.org/users/sawyer_x/2017/12/perl-5-porters-mailing-list-summary-november-21st---december-5th.html: Perl 5 Porters Mailing List Summary: November 21st - December 5th
    http://blogs.perl.org/users/ovid/2017/12/why-i-wrote-keyworddevelopment.html: Why I wrote Keyword::DEVELOPMENT
    http://blogs.perl.org/users/ovid/2017/12/why-i-wrote-keyworddevelopment.html: And here we go!
    https://p6weekly.wordpress.com/2017/12/04/2017-49-mischieventing/: 2017.49 Mischieventing
    http://blogs.perl.org/users/brian_d_foy/2017/12/nominate-perl-heroes-for-the-2017-white-camel-awards.html: Nominate Perl heroes for the 2017 White Camel Awards
    http://news.perlfoundation.org/2017/12/call-for-volunteers.html: Call for volunteers - TPC::NA 2018 (formerly knows as YAPC::NA)
    http://news.perlfoundation.org/2017/11/booking-sponsors-the-perl-5.html: Booking.com Sponsors the P5CMF
    http://niceperl.blogspot.com/: NICEPERL&#38;#39;s lists
    https://perlmaven.com/open-to-read-and-write: Open file to read and write in Perl, oh and lock it too
    https://www.patreon.com/szabgab: Patreon for Gabor
    https://perl.careers/jobs/rapid-growth-in-perl---developers-wanted-for-an-expanding-central-london-company/?utm_source=perlweekly&#38;amp;utm_campaign=perlweekly&#38;amp;utm_medium=perlweekly: Rapid Growth in Perl - developers wanted for an expanding central London company
    https://perl.careers/jobs/be-a-trailblazer-in-a-time-of-growth---full-stack-architect-required-for-a-rapidly-expanding-london-company/?utm_source=perlweekly&#38;amp;utm_campaign=perlweekly&#38;amp;utm_medium=perlweekly: Be a trailblazer in a time of growth - Full Stack Architect required for a rapidly expanding London company
    https://perl.careers/jobs/londons-trendiest-office-space---lead-perl-developer/?utm_source=perlweekly&#38;amp;utm_campaign=perlweekly&#38;amp;utm_medium=perlweekly: London&#38;#39;s Trendiest Office Space - Lead and Mid-Level Perl Developer roles&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But oh dear, some of those links are really really long. Maybe we should use a URL shortener service to make these shorter?&lt;/p&gt;

&lt;p&gt;Google&#38;#39;s URL shortener works by posting a JSON data structure of the form:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    {
        &#38;quot;longURL&#38;quot;: &#38;quot;https://developers.google.com/url-shortener/v1/getting_started&#38;quot;
    }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To the URL &lt;code&gt;https://www.googleapis.com/urlshortener/v1/url?key=???&lt;/code&gt; where the key is the API key obtained by clicking on the &lt;code&gt;GET A KEY&lt;/code&gt; button in the &lt;a href=&#34;https://developers.google.com/url-shortener/v1/getting_started&#34;&gt;Google URL Shortener documentation&lt;/a&gt;. It returns a JSON data structure of the form&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    {
      &#38;quot;kind&#38;quot;: &#38;quot;urlshortener#url&#38;quot;,
      &#38;quot;id&#38;quot;: &#38;quot;https://goo.gl/xwCNC&#38;quot;,
      &#38;quot;longUrl&#38;quot;: &#38;quot;https://developers.google.com/url-shortener/v1/getting_started&#38;quot;
    }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Doing this with &lt;code&gt;ojo&lt;/code&gt; is straight forward. Instead of using &lt;code&gt;g&lt;/code&gt; to make a GET request, we use &lt;code&gt;p&lt;/code&gt; to make a POST request. Using &lt;code&gt;json =&#38;gt; ...&lt;/code&gt; we can pass in the datastructure to be serialized as JSON and posted to the URL.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;ojo&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;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;p&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;double&#34;&gt;&#38;quot;https://www.googleapis.com/urlshortener/v1/url?key=$ENV{API_KEY}&#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;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;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;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;longUrl&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;https://developers.google.com/url-shortener/v1/getting_started&#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;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&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;text&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But of course we don&#38;#39;t want the response from the server as a string, we want it as a Perl data structure so we can grab the id field. That&#38;#39;s as simple as using &lt;code&gt;json&lt;/code&gt; instead of &lt;code&gt;text&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;ojo&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;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;p&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;double&#34;&gt;&#38;quot;https://www.googleapis.com/urlshortener/v1/url?key=$ENV{API_KEY}&#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;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;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;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;longUrl&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;https://developers.google.com/url-shortener/v1/getting_started&#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;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&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;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;id&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or, even better, we can pass a &lt;a href=&#34;https://tools.ietf.org/html/rfc6901&#34;&gt;JSON pointer&lt;/a&gt; to &lt;code&gt;json&lt;/code&gt; and have it extract the value we actually want for us&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;ojo&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;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;p&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;double&#34;&gt;&#38;quot;https://www.googleapis.com/urlshortener/v1/url?key=$ENV{API_KEY}&#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;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;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;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;longUrl&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;https://developers.google.com/url-shortener/v1/getting_started&#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;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&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;json&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;/id&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rolling that back into our original code like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;ojo&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;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;http://perlweekly.com/archive/333.html&#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;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;double&#34;&gt;&#38;quot;.entry-title a&#38;quot;&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;map&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;word&#34;&gt;p&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;double&#34;&gt;&#38;quot;https://www.googleapis.com/urlshortener/v1/url?key=$ENV{API_KEY}&#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;&#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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&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;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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;longUrl&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;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;attr&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;href&#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;&#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;&#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;json&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;/id&#38;quot;&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&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;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\n&#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;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;join&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Produces the output we&#38;#39;d like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    https://goo.gl/wS2jSu: Perl Advent Calendar
    https://goo.gl/B7HqqD: Perl 6 Advent Calendar
    https://goo.gl/xGpyAy: Mojolicious Advent Calendar
    https://goo.gl/f9LBKS: Advent Planet 2017
    https://goo.gl/8aigk1: London Perl Workshop 2017 - Talks Review
    https://goo.gl/j2FzgA: Perl 5 Porters Mailing List Summary: November 21st - December 5th
    https://goo.gl/ptZRF3: Why I wrote Keyword::DEVELOPMENT
    https://goo.gl/ptZRF3: And here we go!
    https://goo.gl/GxETF8: 2017.49 Mischieventing
    https://goo.gl/8q2g21: Nominate Perl heroes for the 2017 White Camel Awards
    https://goo.gl/VCCoHc: Call for volunteers - TPC::NA 2018 (formerly knows as YAPC::NA)
    https://goo.gl/9BRvSA: Booking.com Sponsors the P5CMF
    https://goo.gl/XmJ1wT: NICEPERL&#38;#39;s lists
    https://goo.gl/zPKg2u: Open file to read and write in Perl, oh and lock it too
    https://goo.gl/RChQDF: Patreon for Gabor
    https://goo.gl/wn3c2Q: Rapid Growth in Perl - developers wanted for an expanding central London company
    https://goo.gl/mVZGDQ: Be a trailblazer in a time of growth - Full Stack Architect required for a rapidly expanding London company
    https://goo.gl/4UZctX: London&#38;#39;s Trendiest Office Space - Lead and Mid-Level Perl Developer roles&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;</summary><updated>2017-12-15T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Prereqing around the Christmas Tree</title><link href="http://perladvent.org/2017/2017-12-14.html"/><id>http://perladvent.org/2017/2017-12-14.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Mincepie Frostystockings was elated. The Wise Old Elf had just given him permission to port a bunch of little scripts that he&#38;#39;d been using on his development machine to the main North Pole git repository. From there they&#38;#39;d be deployed to the production machines and available for the entire devops team to use to help debug ongoing live issues.&lt;/p&gt;

&lt;p&gt;&#38;quot;Just don&#38;#39;t forget to make sure the dependencies are installed&#38;quot;, were the Wise Old Elf&#38;#39;s parting words.&lt;/p&gt;

&lt;p&gt;Mincepie scratched his chin. He hadn&#38;#39;t exactly been keeping track of dependencies when he&#38;#39;d written these scripts. They&#38;#39;d grown organically with him just installing whatever he&#38;#39;d needed to get it work with &lt;code&gt;cpanm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How was he going to work out exactly what his requirements are?&lt;/p&gt;

&lt;h3 id=&#34;Technique-1:-Hooking-INC&#34;&gt;Technique 1: Hooking @INC&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@INC&lt;/code&gt; is a global variable that holds all the locations that perl will look for modules when it attempts to load a module&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ /usr/bin/perl -E &#38;#39;say for @INC&#38;#39;
    /Library/Perl/5.18/darwin-thread-multi-2level
    /Library/Perl/5.18
    /Network/Library/Perl/5.18/darwin-thread-multi-2level
    /Network/Library/Perl/5.18
    /Library/Perl/Updates/5.18.2
    /System/Library/Perl/5.18/darwin-thread-multi-2level
    /System/Library/Perl/5.18
    /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.18
    .&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you &lt;code&gt;use lib qw(...)&lt;/code&gt; it&#38;#39;s this variable that Perl is modifying.&lt;/p&gt;

&lt;p&gt;Perl also lets you put other things than simple strings in &lt;code&gt;@INC&lt;/code&gt;, for example a subroutine reference. This subroutine reference will be called every time a module is required and is given the chance to return the code that perl should load (this is how tools like PAR can provide modules directly from a zipfile.)&lt;/p&gt;

&lt;p&gt;You can abuse this mechanism to provide debugging each time something is loaded:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# use a BEGIN block so the code is executed before all&lt;br /&gt;# the &#39;use&#39; statements&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;BEGIN&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;unshift&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@INC&lt;/span&gt;&lt;span class=&#34;operator&#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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#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;$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;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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;say&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;br /&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;        # don&#39;t return anything, meaning Perl will continue&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;# searching through @INC as before&lt;br /&gt;&lt;/span&gt;        &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;&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;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Data::Dumper&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;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;JSON::PP&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This now prints out the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Carp.pm
    strict.pm
    warnings.pm
    Exporter.pm
    XSLoader.pm
    constant.pm
    warnings/register.pm
    bytes.pm
    overload.pm
    overloading.pm
    Test/More.pm
    Test/Builder/Module.pm
    Test/Builder.pm
    Scalar/Util.pm
    List/Util.pm
    Test2/Util.pm
    Config.pm
    vars.pm
    PerlIO.pm
    Config_heavy.pl
    Config_git.pl
    Test2/API.pm
    Test2/API/Instance.pm
    Test2/Util/Trace.pm
    Test2/Util/HashBase.pm
    mro.pm
    DynaLoader.pm
    Test2/API/Stack.pm
    Test2/Hub.pm
    Test2/Util/ExternalMeta.pm
    Test2/Hub/Subtest.pm
    Test2/Hub/Interceptor.pm
    Test2/Hub/Interceptor/Terminator.pm
    Test2/Event/Ok.pm
    Test2/Event.pm
    Test2/Event/Diag.pm
    Test2/Event/Note.pm
    Test2/Event/Plan.pm
    Test2/Event/Bail.pm
    Test2/Event/Exception.pm
    Test2/Event/Waiting.pm
    Test2/Event/Skip.pm
    Test2/Event/Subtest.pm
    Test2/API/Context.pm
    Test/Builder/Formatter.pm
    Test2/Formatter/TAP.pm
    Test2/Formatter.pm
    Test/Builder/TodoDiag.pm
    JSON/PP.pm
    base.pm
    B.pm&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There&#38;#39;s a few things worth noting about this output:&lt;/p&gt;

&lt;dl&gt;

&lt;dt&gt;The &lt;b&gt;filenames&lt;/b&gt; of what we&#38;#39;re search for are specified, not the module names. i.e. &lt;code&gt;Foo/Bar.pm&lt;/code&gt; not &lt;code&gt;Foo::Bar&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;It&#38;#39;s not just the modules we&#38;#39;re requiring directly, but the modules that our modules require. Test2::Event is listed even though we only required Test::More.&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;Things are only listed once. Even though Test::More itself loads &lt;code&gt;strict&lt;/code&gt; and &lt;code&gt;warnings&lt;/code&gt; they&#38;#39;re not listed a second time after Data::Dumper required them&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;You can easily turn this into a module&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;oreLoadingDebugging&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;unshift&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@INC&lt;/span&gt;&lt;span class=&#34;operator&#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;word&#34;&gt;say&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;1&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;];&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;};&lt;/span&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;/pre&gt;

&lt;p&gt;That you can load from the command line&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    perl -MoreLoadingDebugging -c myscript.pl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By using the &lt;code&gt;-c&lt;/code&gt; flag our script doesn&#38;#39;t actually run past the compiling stage meaning (hopefully) the script won&#38;#39;t actually do anything.&lt;/p&gt;

&lt;h4 id=&#34;The-Downsides-of-This-Technique&#34;&gt;The Downsides of This Technique&lt;/h4&gt;

&lt;p&gt;This is a fairly simple technique that, unfortunately has a few downsides:&lt;/p&gt;

&lt;dl&gt;

&lt;dt&gt;&lt;b&gt;Doesn&#38;#39;t find run time dependencies&lt;/b&gt;. Since we&#38;#39;re only running some of the Perl phases of execution, we won&#38;#39;t find anything that&#38;#39;s conditionally loaded at runtime(e.g. something like &lt;code&gt;eval &#38;#39;use SomethingOptional&#38;#39; if $ENV{FEATURE_NAME}&lt;/code&gt;)&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;&lt;b&gt;Totally unsafe&lt;/b&gt;. Even with the &lt;code&gt;-c&lt;/code&gt; flag there&#38;#39;s a chance that something bad will happen when you do this - you&#38;#39;re actually running Perl code that&#38;#39;s one &lt;code&gt;BEGIN { system(&#38;quot;rm -rf $HOME&#38;quot;) }&lt;/code&gt; from deleting everything you care about on your system. You &lt;i&gt;really&lt;/i&gt; don&#38;#39;t want to do this with untrusted code!&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;&lt;b&gt;Must compile&lt;/b&gt;. If the code you&#38;#39;re using won&#38;#39;t compile on the system - probably because you&#38;#39;re actually missing some of those dependencies - then you can&#38;#39;t effectively use this technique. Mincepie couldn&#38;#39;t analyze the scripts on anything but the setup he&#38;#39;d originally written them on.&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;&lt;b&gt;Filename cleanup&lt;/b&gt;. This technique won&#38;#39;t give you a clean set of dependencies you can easily work with. The list contains things in the wrong form &lt;code&gt;Foo/Bar.pm&lt;/code&gt; rather than &lt;code&gt;Foo::Bar&lt;/code&gt;, and is peppered with things that are core pragma (&lt;code&gt;base.pm&lt;/code&gt;, &lt;code&gt;mro.pm&lt;/code&gt;) and core modules that you wouldn&#38;#39;t necessarily need to list as a dependency.&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;dt&gt;&lt;b&gt;Indirect dependencies&lt;/b&gt;. The listed dependencies also contains things that are your dependencies&#38;#39; dependencies - your indirect dependencies - and you don&#38;#39;t want to necessarily state in your &lt;code&gt;cpanfile&lt;/code&gt; that you depend on all of those because they might change as your direct dependencies&#38;#39; dependencies change&lt;/dt&gt;
&lt;dd&gt;

&lt;/dd&gt;
&lt;/dl&gt;

&lt;h3 id=&#34;Technique-2:-Parsing-the-source&#34;&gt;Technique 2: Parsing the source&lt;/h3&gt;

&lt;p&gt;An alternative approach to executing the code is to attempt to write a program that parses it and works out what all the &lt;code&gt;use&lt;/code&gt; and &lt;code&gt;require&lt;/code&gt; statements are attempting to do. With a dynamic language like Perl it&#38;#39;s not possible for a program to work out &lt;i&gt;every&lt;/i&gt; single possible situation that an elf could conceivably write to import code, but its certainly possible to recognize all the ways a &lt;i&gt;sane&lt;/i&gt; elf might write import statements - even those that aren&#38;#39;t executed every program run!&lt;/p&gt;

&lt;p&gt;To do this Mincepie first tried a module on the CPAN &lt;a href=&#34;https://metacpan.org/module/Perl::PrereqScanner&#34;&gt;Perl::PrereqScanner&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner&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;$scanner&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$requirements&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$scanner&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;scan_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;myscript.pl&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The returned &lt;code&gt;$requirements&lt;/code&gt; is a &lt;a href=&#34;https://metacpan.org/module/CPAN::Meta::Requirements&#34;&gt;CPAN::Meta::Requirements&lt;/a&gt; object. You can do a lot with this - including &lt;a href=&#34;https://metacpan.org/module/..#html&#34;&gt;graphing it&lt;/a&gt; - but the simplest thing you can do is just dump it out as a hash;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;JSON::PP&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(encode_json)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;encode_json&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$requirements&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;as_string_hash&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This helpfully prints out in the above example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    {&#38;quot;Data::Dumper&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;JSON::PP&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;Test::More&#38;quot;:&#38;quot;0&#38;quot;}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works on Moose code also:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Rudolph&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;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;extends&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;SantasReindeer&#39;&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;GlowingRedNose&#39;&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;/code&gt;&lt;/pre&gt;

&lt;p&gt;Scanning this correctly shows our dependencies:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    {&#38;quot;GlowingRedNose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;Moose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;SantasReindeer&#38;quot;:&#38;quot;0&#38;quot;}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Speeding-things-up-with-Perl::PrereqScanner::Lite&#34;&gt;Speeding things up with Perl::PrereqScanner::Lite&lt;/h3&gt;

&lt;p&gt;The only problem with using Perl::PrereqScanner is that it&#38;#39;s relatively slow. Under the hood it uses PPI, a Perl parsing library that builds a comprehensive object tree representing each keyword, symbol, structure, etc of the source code. It&#38;#39;s powerful - but slow.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ time perl scan-moose-example.pl
    {&#38;quot;Moose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;GlowingRedNose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;SantasReindeer&#38;quot;:&#38;quot;0&#38;quot;}
    real    0m0.244s
    user    0m0.215s
    sys     0m0.027s&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This might not seem a lot, but when you&#38;#39;re scanning a hundred big files you&#38;#39;re suddenly taking half a minute or so!&lt;/p&gt;

&lt;p&gt;There are alternatives on the CPAN. For example &lt;a href=&#34;https://metacpan.org/module/Perl::PrereqScanner::Lite&#34;&gt;Perl::PrereqScanner::Lite&lt;/a&gt;, which from a user point of view is almost the same to use:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner::Lite&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;$scanner&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner::Lite&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;$scanner&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;add_extra_scanner&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Moose&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;comment&#34;&gt;# add extra scanner for moose style&lt;/span&gt;&lt;br /&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;symbol&#34;&gt;$scanner&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;scan_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Rudolph.pm&#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;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;JSON::PP&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(encode_json)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;encode_json&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;as_string_hash&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But is much faster:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ time perl scan-moose-example-with-lite.pl
    {&#38;quot;SantasReindeer&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;Moose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;GlowingRedNose&#38;quot;:&#38;quot;0&#38;quot;}
    real    0m0.053s
    user    0m0.037s
    sys     0m0.014s&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Finding-optional-dependencies-with-Perl::PrereqScanner::NotSoLite&#34;&gt;Finding optional dependencies with Perl::PrereqScanner::NotSoLite&lt;/h3&gt;

&lt;p&gt;So far our scanners have only found things that our code always depends on. What about optional dependencies? Things we&#38;#39;d &lt;i&gt;like&lt;/i&gt; to load, but work around if they&#38;#39;re not available?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;eval&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;use Term::ANSIColor; 1&#38;quot;&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;say&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;STDERR&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Term::ANSIColor::colored&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;STARTING DEBUGGING&#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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;red on_yellow&#39;&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;span class=&#34;keyword&#34;&gt;else&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;word&#34;&gt;STDERR&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;STARTING DEBUGGING&#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;/pre&gt;

&lt;p&gt;Both Perl::PrereqScanner and Perl::PrereqScanner::Lite won&#38;#39;t detect the dependency on Term::ANSIColor since it&#38;#39;s loaded inside the &lt;code&gt;eval&lt;/code&gt; string. However, &lt;a href=&#34;https://metacpan.org/module/Perl::PrereqScanner::NotSoLite&#34;&gt;Perl::PrereqScanner::NotSoLite&lt;/a&gt; will:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner::NotQuiteLite&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;$scanner&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::PrereqScanner::NotQuiteLite&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;suggests&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;br /&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;symbol&#34;&gt;$scanner&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;scan_file&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Rudolph.pm&#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;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;JSON::PP&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(encode_json)&lt;/span&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;single&#34;&gt;&#39;requires: &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;encode_json&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;requires&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;as_string_hash&lt;/span&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;single&#34;&gt;&#39;suggests: &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;encode_json&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;suggests&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;as_string_hash&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We get &lt;b&gt;two&lt;/b&gt; hashes out, our hard requirements and things we suggest:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    requires: {&#38;quot;Reindeer&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;GlowingRedNose&#38;quot;:&#38;quot;0&#38;quot;,&#38;quot;Moose&#38;quot;:&#38;quot;0&#38;quot;}
    suggests: {&#38;quot;Term::ANSIColor&#38;quot;:&#38;quot;0&#38;quot;}&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Frostystockings-List&#34;&gt;Frostystocking&#38;#39;s List&lt;/h3&gt;

&lt;p&gt;Mincepie Frostystockings had spend a good few hours scanning all his scripts till he was 100% sure that he&#38;#39;d identified everything that they needed to work correctly.&lt;/p&gt;

&lt;p&gt;Now all he had to do was try and work out what the heck &lt;a href=&#34;https://metacpan.org/module/Acme::Damn&#34;&gt;Acme::Damn&lt;/a&gt; was, and why his code was using it...&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-14T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title type="html">It&#38;#39;s All There in the Numbers!</title><link href="http://perladvent.org/2017/2017-12-13.html"/><id>http://perladvent.org/2017/2017-12-13.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;The number of letters Santa received each year was truly staggering requiring the operations team at the North Pole to invest heavily in automation just to keep up. With state of the art OCR and lexical analysis AI to process the inputs - light-years ahead of what the humans were using - they were able to process almost any letter into an ordered list that their fulfillment team could process:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    1 Barbie
    3 Oranges
    24 Coloring pencils&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is why Ponsettia Fairytrifle, head of the Letter Processing Team was surprised when Yule Cuddlefluff, head of the fulfillment team burst into her office door with a complaint right when she was in the middle of morning tea break.&lt;/p&gt;

&lt;p&gt;&#38;quot;It&#38;#39;s no good&#38;quot;, he said, &#38;quot;we&#38;#39;re just getting garbage out the other end. It&#38;#39;ll need to be scrapped. Go back to the old way, with teams of elves reading the letters round the clock&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Just wait a minute&#38;quot;, Ponsettia countered, &#38;quot;before we throw the elfling out with the bathwater, how about you show me what&#38;#39;s wrong?&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;What&#38;#39;s Wrong! What&#38;#39;s Wrong! Just look at this!&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &#38;#2535;&#38;#2536; Shopkins&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Pure garbage!&#38;quot;&lt;/p&gt;

&lt;p&gt;Well, Ponsettia did agree that did look a little unusual, but she thought she&#38;#39;d dig a little before scrapping her entire department. She wondered what those weird characters were, and decided to find out. Perl&#38;#39;s &lt;code&gt;charnames::viacode&lt;/code&gt; is able to print out the name for any unicode codepoint, and &lt;code&gt;ord&lt;/code&gt; can turn any individual character into a codepoint, 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;/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;utf8&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;charnames&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(:full)&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;@chars&lt;/span&gt; &lt;span class=&#34;operator&#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;double&#34;&gt;&#38;quot;&#38;#2535;&#38;#2536;&#38;quot;&lt;/span&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;word&#34;&gt;charnames::viacode&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;ord&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;foreach&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@chars&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;At which point the script printed out:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    BENGALI DIGIT ONE
    BENGALI DIGIT TWO&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And everything became clear! The weird &lt;i&gt;junk&lt;/i&gt; was just numbers in another script! After all, the letters did come in from all around the world...&lt;/p&gt;

&lt;p&gt;&#38;quot;Don&#38;#39;t worry, I can fix this&#38;quot;, Ponsettia explained to Yule, &#38;quot;It&#38;#39;s just a minor change to the code&#38;quot;.&lt;/p&gt;

&lt;p&gt;Unicode::UCD is a core module that has been shipping with Perl since the pre-releases of Perl 5.8. One of the things it can do is turn digits of any script into something Perl will be able treat as a 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;/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;Unicode::UCD&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(num)&lt;/span&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;word&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;&#38;#2535;&#38;#2536;&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# prints &#38;quot;12&#38;quot;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;However, it&#38;#39;s clever enough to return undefined if you start mixing your scripts (as that&#38;#39;s likely pure nonsense)&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Unicode::UCD&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(num)&lt;/span&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;single&#34;&gt;&#39;junk&#39;&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;core&#34;&gt;defined&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;\N{DEVANAGARI DIGIT THREE}\N{CHAM DIGIT TWO}&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A few minutes after Yule had left Ponsettia had already checked in a change to her codebase to make the lists print out the right thing. Disaster quickly averted she returned to her still warm cup of tea.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-13T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>A Christmas Memory</title><link href="http://perladvent.org/2017/2017-12-12.html"/><id>http://perladvent.org/2017/2017-12-12.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;&#38;quot;I just don&#38;#39;t get it!&#38;quot;&lt;/p&gt;

&lt;p&gt;An elf raising his voice was unheard of. Normally softly spoken, Cedar Greentrifle was several decibels above where his voice should have been and getting louder.&lt;/p&gt;

&lt;p&gt;&#38;quot;Mr Greentrifle&#38;quot;, the Wise Old Elf interjected, &#38;quot;May I be of some assistance?&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;It&#38;#39;s this baubling code! It keeps eating all the memory. And I can&#38;#39;t work out why!&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Ah, then maybe this might be a good time to show you a tool I learned about at the London Perl Workshop that might be just the ticket!&#38;quot;&lt;/p&gt;

&lt;h3 id=&#34;Introducing-Devel::MAT&#34;&gt;Introducing Devel::MAT&lt;/h3&gt;

&lt;p&gt;Devel::MAT is a handy dandy command line tool that can help you work out exactly what is taking up the memory in your Perl program. You can trigger a dump summarizing your program&#38;#39;s memory usage at any point in the execution, then load up the &lt;code&gt;pmat&lt;/code&gt; console and poke around in that dump to your heart&#38;#39;s content until you figure out exactly what went wrong.&lt;/p&gt;

&lt;p&gt;Let&#38;#39;s see how to use it on a simple example program that&#38;#39;s going to allocate a &lt;b&gt;huge&lt;/b&gt; string.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;#!/usr/bin/perl&lt;br /&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;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;$elf&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;happy&#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;$elf&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;x=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# 5 Gigs!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order to analyze the memory usage in our code we need to alter it so that it dumps a summary of the memory to a &lt;i&gt;pmat&lt;/i&gt; dump file during the execution of the code. The simplest way to do this is to add a &lt;code&gt;die&lt;/code&gt; statement...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;#!/usr/bin/perl&lt;br /&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;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;$elf&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;happy&#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;$elf&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;x=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# 5 Gigs!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;..then run the same code with the Devel::MAT::Dumper module configured on the command line to hook exception handling so that a dump file is written when the die occurs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ perl -MDevel::MAT::Dumper=-dump_at_DIE script.pl
    Dumping to /Users/Cedar/test/script.pl.pmat because of DIE
    Died at script.pl line 9.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a &lt;i&gt;pmat&lt;/i&gt; dump file on disk named the same as our Perl script with an additional &lt;code&gt;.pmat&lt;/code&gt; extension:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ ls
    script.pl  script.pl.pmat&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can load this into the &lt;code&gt;pmat&lt;/code&gt; interactive console&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ pmat script.pl.pmat
    Perl memory dumpfile from perl 5.22.0
    Heap contains 2366 objects
    pmat&#38;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And away we go. &lt;code&gt;pmat&lt;/code&gt; offers a bunch of commands, all of which can be listed with the &lt;code&gt;help&lt;/code&gt; option.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; help
    callstack - Display the call stack
    count     - Count the various kinds of SV
    elems     - List the elements of an ARRAY SV
    find      - List SVs matching given criteria
    help      - Display a list of available commands
    identify  - Identify an SV by its referrers
    io        - Commands working with IO SVs
    largest   - Find the largest SVs by size
    roots     - Display a list of the root SVs
    show      - Show information about a given SV
    sizes     - Summarize object and byte counts across different SV types
    symbols   - Display a list of the symbol table
    values    - List the values of a HASH-like SV&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;Tracking-down-the-largest-things-in-your-code&#34;&gt;Tracking down the largest things in your code&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;largest&lt;/code&gt; command can be very helpful in tracking down what&#38;#39;s taking up the most space:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; largest
    SCALAR(PV) at 0x7fab7d016a60: 5.0 GiB
    HASH(540) at 0x7fab7d002e90=strtab: 33.6 KiB
    INVLIST() at 0x7fab7e01bf88: 9.9 KiB
    INVLIST() at 0x7fab7e01c018: 9.8 KiB
    STASH(84) at 0x7fab7d0030d0=defstash: 3.1 KiB
    others: 228.5 KiB&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There&#38;#39;s our string, right there at the top: &lt;code&gt;0x7fab7d016a60&lt;/code&gt;. Because our example code was so simple we already know which scalar that is. But, if we didn&#38;#39;t, we could easily ask pmat to identify it for us&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; identify 0x7fab7d016a60
    SCALAR(PV) at 0x7fab7d016a60 is:
    \-the lexical $elf at depth 1 of CODE() at 0x7fab7d003478=main_cv, which is:
      \-the main code&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh, that&#38;#39;s obvious. If our code is a little more complex then things are still descriptive enough for us to understand what&#38;#39;s happening. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;santas_workshop&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;$phrase&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;happy&#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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$elf&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;attributes&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;&lt;span class=&#34;word&#34;&gt;mood&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$phrase&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;1024&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;short&#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;&#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;&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;single&#34;&gt;&#39;Cedar Greentrifle&#39;&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;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;structure&#34;&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Results in the identification:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; identify 0x7f9f9b011860
    SCALAR(PV) at 0x7f9f9b011860 is:
    \-value {state} of HASH(1) at 0x7f9f9b003250, which is:
      \-(via RV) value {attr} of HASH(1) at 0x7f9f9b011878, which is:
        \-(via RV) the lexical $elf at depth 1 of CODE(PP) at 0x7f9f9b016a78, which is:
          \-the symbol &#38;#39;&#38;amp;main::santas_workshop&#38;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, we can easily identify large strings. What about big data structures&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;#!/usr/bin/perl&lt;br /&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;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;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;expand&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;$count&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;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;&lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Merry Christmas&#38;quot;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&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;&#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;&#38;nbsp;&#38;nbsp;&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;word&#34;&gt;expand&lt;/span&gt;&lt;span class=&#34;structure&#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;span class=&#34;structure&#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;number&#34;&gt;10&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;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$big_data_structure&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;expand&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;die&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a tree with a million copies of the string &lt;code&gt;Merry Christmas&lt;/code&gt; in it. What does &lt;code&gt;pmat&lt;/code&gt; make of this?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Perl memory dumpfile from perl 5.22.0
    Heap contains 124628 objects
    pmat&#38;gt; largest
    HASH(548) at 0x7fb053002e90=strtab: 33.9 KiB
    INVLIST() at 0x7fb053085f88: 9.9 KiB
    INVLIST() at 0x7fb053086018: 9.8 KiB
    STASH(85) at 0x7fb0530030d0=defstash: 3.2 KiB
    HASH(70) at 0x7fb0530217c8: 2.7 KiB
    others: 10.4 MiB&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not so helpful, the largest thing is the &lt;code&gt;strtab&lt;/code&gt; (the cache of constant strings used in our code itself.) Not very helpful.&lt;/p&gt;

&lt;p&gt;This is where the &lt;code&gt;--owned&lt;/code&gt; option for &lt;code&gt;largest&lt;/code&gt; comes in handy. This takes a while to execute, but it can work out cumulative sizes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; largest --owned
    CODE() at 0x7fb053003478=main_cv: 10.2 MiB: of which
     |   PAD(3) at 0x7fb053003490: 10.2 MiB: of which
     |    |   REF() at 0x7fb053016ad8: 10.2 MiB
     |    |   HASH(10) at 0x7fb053011950: 10.2 MiB
     |    |   others: 10.2 MiB
     |   SCALAR(UV) at 0x7fb053016a60: 24 bytes
    STASH(85) at 0x7fb0530030d0=defstash: 70.4 KiB: of which
     |   GLOB(%*) at 0x7fb053017918: 22.6 KiB: of which
     |    |   STASH(2) at 0x7fb053021678: 22.4 KiB
     |    |   GLOB(%*) at 0x7fb053034d48: 22.1 KiB
     |    |   others: 22.1 KiB
     |   GLOB(%*) at 0x7fb053080b20: 14.6 KiB: of which
     |    |   STASH(39) at 0x7fb053080b38: 14.5 KiB
     |    |   GLOB(&#38;amp;*) at 0x7fb055015de0: 2.4 KiB
     |    |   others: 12.7 KiB
     |   GLOB(%*) at 0x7fb0530809e8: 3.9 KiB: of which
     |    |   STASH(3) at 0x7fb053080a60: 3.8 KiB
     |    |   GLOB(&#38;amp;*) at 0x7fb053080ad8: 3.3 KiB
     |    |   others: 3.3 KiB
     |   others: 26.1 KiB
    HASH(548) at 0x7fb053002e90=strtab: 33.9 KiB
    REF() at 0x7fb053085fb8: 10.0 KiB: of which
     |   ARRAY(5) at 0x7fb053085fd0: 10.0 KiB: of which
     |    |   INVLIST() at 0x7fb053085f88: 9.9 KiB
     |    |   SCALAR(UV) at 0x7fb053085fa0: 24 bytes
    REF() at 0x7fb0530f1450: 9.9 KiB: of which
     |   ARRAY(5) at 0x7fb053085fe8: 9.9 KiB: of which
     |    |   INVLIST() at 0x7fb053086018: 9.8 KiB
     |    |   SCALAR(UV) at 0x7fb0530f1438: 24 bytes
    others: 162.8 KiB&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the largest thing is unsurprisingly the main code. It owns a &lt;code&gt;REF()&lt;/code&gt; to a data structure at &lt;code&gt;0x7fb053016ad8&lt;/code&gt; that is just over ten megabytes in size. And if we identify that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; identify 0x7fb053016ad8
    REF() at 0x7fb053016ad8 is:
    \-the lexical $big_data_structure at depth 1 of CODE() at 0x7fb053003478=main_cv, which is:
      -\the main code&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...we see it&#38;#39;s the &lt;code&gt;$big_data_structure&lt;/code&gt; we were expecting.&lt;/p&gt;

&lt;h3 id=&#34;Tracking-Down-Leaks&#34;&gt;Tracking Down Leaks&lt;/h3&gt;

&lt;p&gt;Perl uses reference counting to keep track of memory. When a data structure has nothing pointing to it anymore (i.e. no variables point to it, no other parts of a data structure point at it) it&#38;#39;s unreachable by the program and can be cleared away.&lt;/p&gt;

&lt;p&gt;But what happens if we have a data structure point to itself?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$greeting&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$greeting&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;data&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Merry Christmas&#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;link&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;$greeting&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;/pre&gt;

&lt;p&gt;Perl will never be able to reclaim that. The anonymous hash will always be pointed to by the hash value, and the hash value will always be pointed to by the anonymous hash. When &lt;code&gt;$greeting&lt;/code&gt; goes out of scope this will leak memory. Do that enough times and this will be the source of the extra memory your program is using.&lt;/p&gt;

&lt;p&gt;How can we find these? It&#38;#39;s tricky. If the data structure is large enough we can use the &lt;code&gt;largest&lt;/code&gt; technique above. Otherwise, we can search for things in the data structure to see if we&#38;#39;ve got more of these still hanging around than we might expect. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; find pv --eq &#38;#39;Merry Christmas&#38;#39;
    SCALAR(PV) at 0x7fa2d56e3330: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d54fa2d0: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d57a0588: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d5052890: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d3901790: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d29b26a0: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d518f440: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d579dae0: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d391f868: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d2c7a2a8: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d5259f48: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d2c7b1a8: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d297ae00: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d2a53528: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d510f6a0: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d55ce980: &#38;quot;Merry Christmas&#38;quot;
    SCALAR(PV) at 0x7fa2d401d0d8: &#38;quot;Merry Christmas&#38;quot;
    ...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;identify&lt;/code&gt; can tell us a little about each of these scalars (including that it has a loop), but obviously not which variable holds them (because none does):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; identify 0x7fa2d56e3330
    SCALAR(PV) at 0x7fa2d56e3330 is:
    \-value {data} of HASH(2) at 0x7fa2d56e3300, which is (*A):
      \-(via RV) the referrant of REF() at 0x7fa2d56e3348, which is:
        \-value {link} of HASH(2) at 0x7fa2d56e3300, which is:
          \-already found as *A&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might be tempted to search for a hash key. This won&#38;#39;t go as well:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    pmat&#38;gt; find pv --eq &#38;#39;data&#38;#39;
    SCALAR(PV) at 0x7fa2d2003340: &#38;quot;data&#38;quot;

    pmat&#38;gt; identify 0x7fa2d2003340
    SCALAR(PV) at 0x7fa2d2003340 is:
    \-a constant of CODE() at 0x7fa2d2003478=main_cv, which is:
      \-the main code&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&#38;#39;s because internally perl doesn&#38;#39;t keep a copy of the hash key inside each hash - the one and only scalar containing &lt;code&gt;data&lt;/code&gt; is the one perl created for the constant string used in the code itself.&lt;/p&gt;

&lt;h3 id=&#34;A-Happy-Elf&#34;&gt;A Happy Elf&lt;/h3&gt;

&lt;p&gt;&#38;quot;I GOT IT I GOT IT I GOT IT&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Mr Greentrifle! Please keep the noise down...&#38;quot;&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-12T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Tiny Path Handling</title><link href="http://perladvent.org/2017/2017-12-11.html"/><id>http://perladvent.org/2017/2017-12-11.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Path::Tiny is a tiny abstraction around file paths that makes it very easy to manipulate them and perform common operations on them.&lt;/p&gt;

&lt;p&gt;Recently I&#38;#39;ve started using Path::Tiny in preference to both the internal Perl operators for file manipulation and the other abstractions like File::Spec and Path::Class because it makes it really easy to handle common operations easily without making the kind of common mistakes that those other approaches often result in when you&#38;#39;re coding quickly.&lt;/p&gt;

&lt;p&gt;Enough explaining, let&#38;#39;s see how to use Path::Tiny in practice...&lt;/p&gt;

&lt;h3 id=&#34;Building-New-Path::Tiny-instances&#34;&gt;Building New Path::Tiny instances&lt;/h3&gt;

&lt;p&gt;Construction of paths is simple: The &lt;code&gt;path&lt;/code&gt; function just takes an absolute or relative path.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Path::Tiny&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( path )&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;# the password file&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$passwords&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;/etc/passwd&#39;&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;# my home directory&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;   &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$ENV&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;HOME&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see Path::Tiny makes no distinction between directories or files - it relies entirely on you doing the right operations on them.&lt;/p&gt;

&lt;p&gt;These objects stringify directly into the string form of the path so on my macOS machine this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Prints&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    /Users/Mark&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Paths can be extended with the &lt;code&gt;child&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# this is &#39;/Users/Mark/shopping_lists/xmas.txt&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;shopping_lists&#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;child&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;xmas.txt&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This could have been written as:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;shopping_lists&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;xmas.txt&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;shopping_lists/xmas.txt&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

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

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$relative_path&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;shopping_lists/xmas.txt&#39;&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;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;child&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$relative_path&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or even with the &lt;code&gt;path&lt;/code&gt; constructor function like any of these:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;shopping_list&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;xmas.txt&#39;&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;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;shopping_list/xmas.txt&#39;&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;$xmas_list&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$homedir&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;shopping_list/xmas.txt&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;));&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, using Path::Tiny makes combining paths really simple and helps me avoid one of the biggest problems I always end up with - if the directory path has a trailing slash or not&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$dir&lt;/span&gt;                 &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;/Users/Mark/shopping_list&#39;&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;$with_trailing_slash&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$dir/&#38;quot;&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;$file&lt;/span&gt;                &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;mia_birthday.txt&#39;&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;# WRONG: prints &#38;quot;/Users/Mark/shopping_listmia_birthday.txt&#38;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$dir$file&#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;comment&#34;&gt;# WRONG: prints &#38;quot;/Users/Mark/shopping_list//mia_birthday.txt&#38;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$with_trailing_slash/$file&#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;comment&#34;&gt;# RIGHT: both prints &#38;quot;/Users/Mark/shopping_list/mia_birthday.txt&#38;quot;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$dir&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;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$with_trailing_slash&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;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A Path::Tiny object can also be broken down into the parent directory or the filename without the directory part (the &lt;i&gt;basename&lt;/i&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# This prints &#39;/Users/Mark/shopping_list&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;parent&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 prints &#39;xmas.txt&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;basename&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This sure beats having to use a regular expression on the path string - that too can get very complicated with trailing slashes..&lt;/p&gt;

&lt;h3 id=&#34;Reading-and-Writing-Files&#34;&gt;Reading and Writing Files&lt;/h3&gt;

&lt;p&gt;While easy path manipulation is awesome, where Path::Tiny really shines is how it makes common file operations simple and only one line long:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# add to the end of the file&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;A partridge for the pair tree\n&#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;comment&#34;&gt;# read in the entire file as single string, then write it out again&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$contents&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;slurp&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$contents&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/pair/pear/g&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;spew&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$contents&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, in this day and age we should really be using UTF-8 encoding. Path::Tiny makes this trivial by providing the &lt;code&gt;_utf8&lt;/code&gt; suffix for all the file reading / writing methods which Does The Right Thing:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;append_utf8&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;A \N{BIRD} for the \N{PEAR}\N{DECIDUOUS TREE}&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not shown is Path::Tiny Doing The Right Thing when appending to a file when it comes to multiple processes writing to the file at the same time. In traditional Perl code you should open the filehandle you&#38;#39;re about to write to and then flock it for the duration you have the file open so that any other code that also takes these two steps will wait for the other process to complete writing and you to release the flock before taking its turn. In reality, most coders skip this step and just hope that they remain lucky that such a conflict doesn&#38;#39;t occur ending up with two processes writing to the file at exactly the same time. Path::Tiny handles all of that for you so you don&#38;#39;t have to.&lt;/p&gt;

&lt;p&gt;Path::Tiny has a slew of handy methods for common reading and writing operations on a file. For example, it can also read a file in as an array of lines:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# sort our Christmas list&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;spew_utf8&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;sort&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;lines_utf8&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or alter each line in the file and atomically write the file contents back:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#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;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$xmas_list&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;edit_lines_utf8&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;magic&#34;&gt;$_&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;$counter. $_&#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;$counter&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;/pre&gt;

&lt;p&gt;Rather than list every single handy-dandy operation that Path::Tiny provides in this article - including reading directory contents (or iterating over them via an iterator function or via callback), opening temp files, absolute and relative path conversion, file testing, copying, removing directory trees and much more - I encourage you to peruse the extensive documentation.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-11T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Evaluating the NaughtyNice Formula</title><link href="http://perladvent.org/2017/2017-12-10.html"/><id>http://perladvent.org/2017/2017-12-10.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;As we talked about yesterday, Sugarplum Stripyboughs was developing a system where a formula was stored in the database could be used to calculate the NaughtyNice Formula for a particular gift for a particular child. Using a recursive regular expression she&#38;#39;d already verified that the formula string was valid. Now she had to work out how to execute it.&lt;/p&gt;

&lt;h3 id=&#34;Turning-the-Formula-into-Perl-Code&#34;&gt;Turning the Formula into Perl Code&lt;/h3&gt;

&lt;p&gt;One approach to executing the formula might be build some sort of evaluation engine in code that could interpret the formula - though this would be quite complicated to do and run slowly! A simpler, and more performant, technique would be to transform the formula into Perl code.&lt;/p&gt;

&lt;p&gt;Remember, the formula Sugarplum has to execute looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  (number_of_tantrums/6)+(age/12*(teeth_brushs_this_year+flosses_this_year))/2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The corresponding Perl code for this would be the following, more or less:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#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;&lt;span class=&#34;keyword&#34;&gt;return&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;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;]{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;number_of_tantrums&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;6&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;operator&#34;&gt;+&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;number&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;]{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;age&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;12&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;&#38;nbsp;&#38;nbsp;&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;span class=&#34;word&#34;&gt;teeth_brushs_this_year&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;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;flosses_this_year&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;span class=&#34;operator&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;2&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which could then be called like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;symbol&#34;&gt;$formula&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;age&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;12&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;number_of_tantrums&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;49&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;teeth_brushs_this_year&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;721&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;flosses_this_year&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;321&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;/pre&gt;

&lt;p&gt;Turning the validated expression into code is reasonably straight forward - we just need to convert the variables in the expression into Perl variables as everything else is already valid Perl code.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;build_formula&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;$formula&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;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;    # replace foo_bar -&#38;gt; $_[0]{foo_bar}&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s{([a-z_]+)}{\$_[0]{$1}}g&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;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;sub { $formula }&#38;quot;&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;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;/pre&gt;

&lt;h3 id=&#34;Closing-over-variables&#34;&gt;Closing over variables&lt;/h3&gt;

&lt;p&gt;It turns out that several of the variables that the elves over in the Niceness Assurance Department wanted to use in the formula weren&#38;#39;t related to the child at all. Things like the value of the gift and number left in stock are instead related to database attributes for that gift, and they need to pass these values in at the time the formula is compiled.&lt;/p&gt;

&lt;p&gt;&#38;quot;Hmm,&#38;quot; thought Sugarplum Stripyboughs to herself, &#38;quot;How can I do that?&#38;quot; She decided to extend the previous grammar to allow uppercase constants.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&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;single&#34;&gt;&#39;good_deeds/GIFT_VALUE*STOCK&#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;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$playing_cards&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;build_formula&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;$string&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;gift_value&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;stock&lt;/span&gt;      &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;100&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;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$real_elephant&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;build_formula&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;$string&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;gift_value&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;10_000&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;stock&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;/pre&gt;

&lt;p&gt;Now all she had to do was rewrite her conversions regular expressions to allow upper case variables to be used in the calculation.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;build_formula&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;$formula&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%args&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$GIFT_VALUE&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$args&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gift_value&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;$STOCK&lt;/span&gt;      &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$args&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;stock&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;    # replace FOO_BAR -&#38;gt; $FOO_BAR&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s{([A-Z][A-Z_]*)}{\$$1}g&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;    # replace foo_bar -&#38;gt; $_[0]{foo_bar}&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s{([a-z][a-z_]*)}{\$_[0]{$1}}g&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;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;sub { $formula }&#38;quot;&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;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;/pre&gt;

&lt;p&gt;Sugarplum was taking advantage of the way perl&#38;#39;s memory management works to &lt;i&gt;close over&lt;/i&gt; the constants in the subroutine. Each subroutine reference that &lt;code&gt;build_formula&lt;/code&gt;&#38;#39;s &lt;code&gt;eval&lt;/code&gt; creates &lt;i&gt;sees&lt;/i&gt; the particular version of &lt;code&gt;$GIFT_VALUE&lt;/code&gt; and &lt;code&gt;$STOCK&lt;/code&gt; that was assigned in that subroutine only and &lt;i&gt;closes over&lt;/i&gt; them retaining their value.&lt;/p&gt;

&lt;p&gt;She deployed the updated code and started happily working on the next story in the backlog.&lt;/p&gt;

&lt;h3 id=&#34;The-Mistake-and-a-Solution&#34;&gt;The Mistake, and a Solution&lt;/h3&gt;

&lt;p&gt;When Sugarplum got back to work early the next data she discovered that one of the elves in the Niceness Assurance Department had created a ticket.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Value for COST is wrong&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wait, what? There was no &lt;code&gt;$COST&lt;/code&gt; variable in this subroutine! After staring at her editor for a few minutes she was stumped. In a last ditch effort she tried searching for the string. And then she found it....at the top of the file, in a totally unrelated part of the code&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# boolean to enable/disable cost tracking functionality&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$COST&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;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ooooh, that&#38;#39;s right. The &lt;code&gt;eval&lt;/code&gt; will close over &lt;i&gt;any&lt;/i&gt; variable that&#38;#39;s in scope, including those we don&#38;#39;t want it to, letting anyone use anything from anywhere despite it having nothing to do with the formula calculations. What Sugarplum needed was a way to convince Perl which variables she wanted, and which she didn&#38;#39;t.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&#34;https://metacpan.org/module/Eval::Closure&#34;&gt;Eval::Closure&lt;/a&gt; from the CPAN.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;build_formula&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;$formula&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%args&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;    # replace FOO_BAR -&#38;gt; $FOO_BAR&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s{([A-Z][A-Z_]*)}{\$$1}g&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;    # replace foo_bar -&#38;gt; $_[0]{foo_bar}&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;symbol&#34;&gt;$formula&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s{([a-z][a-z_]*)}{\$_[0]{$1}}g&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;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;eval_closure&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;source&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;sub { $formula }&#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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;environment&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;&lt;span class=&#34;single&#34;&gt;&#39;$GIFT_VALUE&#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;$args&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;gift_value&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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;single&#34;&gt;&#39;$STOCK&#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;$args&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;stock&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;&#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;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Eval::Closure lets us control exactly which variables the code we compile has access to! Passing in an invalid formula like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  age/COST&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Results in a proper error being thrown even when a &lt;code&gt;$COST&lt;/code&gt; is in scope&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  Failed to compile source: Global symbol &#38;quot;$COST&#38;quot; requires explicit
  package name (did you forget to declare &#38;quot;my $COST&#38;quot;?) at (eval 5) line 5.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That bug was fixed! Now all Sugarplum had left to do was head down to the Niceness Assurance Department to inquire exactly what they expected &lt;code&gt;COST&lt;/code&gt; to do....&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-10T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Matching the NaughtyNice Formula</title><link href="http://perladvent.org/2017/2017-12-09.html"/><id>http://perladvent.org/2017/2017-12-09.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Back in the day, you were either Naughty or Nice, and you either got coal or presents from Santa. But Santa had decided that this was a little too all or nothing. So he had tasked his Elf R&#38;amp;D department to develop an application that could determine on a case by case basis if the the child had been &lt;i&gt;good&lt;/i&gt; enough for &lt;i&gt;that particular gift&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;For example, a child who couldn&#38;#39;t sit still when asked probably shouldn&#38;#39;t get that eighty pound bar of chocolate that they wanted no matter how often they&#38;#39;d tidied their room. The new art supplies that little Suzy wanted shouldn&#38;#39;t really go to the girl that had doodled over the dining room table with the permanent marker. It was a &lt;i&gt;complicated&lt;/i&gt; issue.&lt;/p&gt;

&lt;p&gt;The elves had decided that each gift should have a NaughtyNice Formula associated with it - an expression stored in the database that could be used to decide if the child deserved that item.&lt;/p&gt;

&lt;p&gt;Sugarplum Stripyboughs had been tasked with building the web forms that acted as a front end for the database that all the pointy eared Elves over in the Niceness Assurance Department could use to enter the formula.&lt;/p&gt;

&lt;p&gt;The bit she was stuck on was validating the formulas that the Elves were entering in the web app - that they were semantically correct and okay to store in the database. A typical formula might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;     (number_of_tantrums/6)+(age/12*(teeth_brushes_this_year+flosses_this_year))/2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is to say some variables, some integers, stuck together with brackets and the standard four arithmetic operators (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, and &lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Writing a regular expression to match this kind of expression without worring about those brackets is fairly straight forward stuff. But those brackets have to match each other. Sugarplum needed to be able to tell that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;     (number_of_a_grades-number_of_c_grades+(days_missed_of_school)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just wasn&#38;#39;t a valid formula - it&#38;#39;s missing the last closing &lt;code&gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The trouble is that expressions like this aren&#38;#39;t a &#38;quot;Type-3&#38;quot; grammar on the Chomsky hierarchy - the type of grammars a traditional regular expression engine can match. Simply: To match the number of closing brackets with the number of opening brackets, you need to keep count of the number of times you saw an opening bracket, and a traditional regular expression engine can&#38;#39;t do that.&lt;/p&gt;

&lt;p&gt;Perl, on the other hand, has a more powerful regular expression engine that can handle these kinds of matches.&lt;/p&gt;

&lt;h3 id=&#34;Backus-Naur-Form&#34;&gt;Backus-Naur Form&lt;/h3&gt;

&lt;p&gt;BNF is a way of specifying a grammar formally. Sugarplum quickly whipped up one for the formulas she was trying to match.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &#38;lt;letter&#38;gt;     ::= &#38;quot;a&#38;quot; | &#38;quot;b&#38;quot; | &#38;quot;c&#38;quot; | &#38;quot;d&#38;quot; | &#38;quot;e&#38;quot; | &#38;quot;f&#38;quot; | &#38;quot;g&#38;quot; | &#38;quot;h&#38;quot; | &#38;quot;i&#38;quot; | &#38;quot;j&#38;quot; |
                  &#38;quot;k&#38;quot; | &#38;quot;l&#38;quot; | &#38;quot;m&#38;quot; | &#38;quot;n&#38;quot; | &#38;quot;o&#38;quot; | &#38;quot;p&#38;quot; | &#38;quot;q&#38;quot; | &#38;quot;r&#38;quot; | &#38;quot;s&#38;quot; | &#38;quot;t&#38;quot; |
                  &#38;quot;u&#38;quot; | &#38;quot;v&#38;quot; | &#38;quot;w&#38;quot; | &#38;quot;x&#38;quot; | &#38;quot;y&#38;quot; | &#38;quot;z&#38;quot;
 &#38;lt;unders&#38;gt;     ::= &#38;lt;letter&#38;gt; | &#38;quot;_&#38;quot; | &#38;lt;letter&#38;gt; &#38;lt;unders&#38;gt; | &#38;quot;_&#38;quot; &#38;lt;unders&#38;gt;
 &#38;lt;variable&#38;gt;   ::= &#38;lt;letter&#38;gt; | &#38;lt;letter&#38;gt; &#38;lt;unders&#38;gt;

 &#38;lt;digit&#38;gt;      ::= &#38;quot;0&#38;quot; | &#38;quot;1&#38;quot; | &#38;quot;2&#38;quot; | &#38;quot;3&#38;quot; | &#38;quot;4&#38;quot; | &#38;quot;5&#38;quot; | &#38;quot;6&#38;quot; | &#38;quot;7&#38;quot; | &#38;quot;8&#38;quot; | &#38;quot;9&#38;quot;
 &#38;lt;startdigit&#38;gt; ::= &#38;quot;1&#38;quot; | &#38;quot;2&#38;quot; | &#38;quot;3&#38;quot; | &#38;quot;4&#38;quot; | &#38;quot;5&#38;quot; | &#38;quot;6&#38;quot; | &#38;quot;7&#38;quot; | &#38;quot;8&#38;quot; | &#38;quot;9&#38;quot;
 &#38;lt;digits&#38;gt;     ::= &#38;lt;digit&#38;gt; | &#38;lt;digit&#38;gt; &#38;lt;digits&#38;gt;
 &#38;lt;number&#38;gt;     ::= &#38;lt;startdigit&#38;gt; | &#38;lt;startdigit&#38;gt; &#38;lt;digits&#38;gt;

 &#38;lt;oper&#38;gt;       ::= &#38;quot;+&#38;quot; | &#38;quot;-&#38;quot; | &#38;quot;*&#38;quot; | &#38;quot;/&#38;quot;
 &#38;lt;bracket&#38;gt;    ::= &#38;quot;(&#38;quot; &#38;lt;expression&#38;gt; &#38;quot;)&#38;quot;
 &#38;lt;thing&#38;gt;      ::= &#38;lt;number&#38;gt; | &#38;lt;variable&#38;gt; | &#38;lt;bracket&#38;gt;
 &#38;lt;expression&#38;gt; ::= &#38;lt;thing&#38;gt; | &#38;lt;thing&#38;gt; &#38;lt;oper&#38;gt; &#38;lt;expression&#38;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That was...better? She decided to make it a bit more readable by turning some of the overly wordy bits into standard regular expression syntax&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &#38;lt;variable&#38;gt;   ::= qr/[a-z][a-z_]*/
    &#38;lt;number&#38;gt;     ::= qr/[1-9][0-9]*/
    &#38;lt;oper&#38;gt;       ::= qr/[+*/-]/
    &#38;lt;bracket&#38;gt;    ::= &#38;quot;(&#38;quot; &#38;lt;expression&#38;gt; &#38;quot;)&#38;quot;
    &#38;lt;thing&#38;gt;      ::= &#38;lt;number&#38;gt; | &#38;lt;variable&#38;gt; | &#38;lt;bracket&#38;gt;
    &#38;lt;expression&#38;gt; ::= &#38;lt;thing&#38;gt; | &#38;lt;thing&#38;gt; &#38;lt;oper&#38;gt; &#38;lt;expression&#38;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Okay, that&#38;#39;s a lot clearer. Now to turn this into a Perl regular expression!&lt;/p&gt;

&lt;h3 id=&#34;Named-Capture-Groups&#34;&gt;Named Capture Groups&lt;/h3&gt;

&lt;p&gt;In Perl you can create named capture groups in your regular expressions:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;James Bond&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/^ (?&#38;lt;first&#38;gt;\S+) \s* (?&#38;lt;last&#38;gt;\S+) $/x&lt;/span&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;double&#34;&gt;&#38;quot;The name&#39;s $+{last}, $+{first} $+{last}&#38;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#38;#39;s actually possible to use named capture blocks to create a sort of library of reusable named regular expressions inside a regular expression:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Matches&#38;quot;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&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;match&#34;&gt;m{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?(DEFINE)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;wise&#38;gt; Melchior | Caspar | Balthazar )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;gift&#38;gt; gold | frankincense | myrrh )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;)&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?:&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;amp;wise) [ ] (brought|gave) [ ](?&#38;amp;gift) |&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;amp;gift) [ ] was [ ] (brought|given) [ ] by [ ] (?&#38;amp;wise)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;)&lt;br /&gt;}x&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Everything within the &lt;code&gt;(?(DEFINE) ... )&lt;/code&gt; block isn&#38;#39;t actually matched until the various named blocks are called with the &lt;code&gt;(?&#38;amp;block_name)&lt;/code&gt; syntax.&lt;/p&gt;

&lt;p&gt;While having this sort of library of named parts of a regular expression is nice from a readability point of view, the real power comes from the fact that these definitions can themselves reference other named capture blocks recursively. This allowed Sugarplum to basically directly port the BNF into a Perl regular expression:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Matches&#38;quot;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;if&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;match&#34;&gt;m{&lt;br /&gt;&#38;nbsp;&#38;nbsp;(?(DEFINE)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;variable&#38;gt;    [a-z][_a-z]* )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;number&#38;gt;      [1-9][0-9]* )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;oper&#38;gt;        [+*/-] )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;bracket&#38;gt;     [(] (?&#38;amp;expression) [)] )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;thing&#38;gt;       (?&#38;amp;number) | (?&#38;amp;variable) | (?&#38;amp;bracket) )&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;(?&#38;lt;expression&#38;gt;  (?&#38;amp;thing) | (?&#38;amp;thing) (?&#38;amp;oper) (?&#38;amp;expression) )&lt;br /&gt;&#38;nbsp;&#38;nbsp;)&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;\A (?&#38;amp;expression) \z&lt;br /&gt;}x&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With that regular expression written Sugarplum was done with the hard part...unless someone wanted her to write code to execute the formula that is... (to be continued)&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-09T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Constantly Merry</title><link href="http://perladvent.org/2017/2017-12-08.html"/><id>http://perladvent.org/2017/2017-12-08.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;One of the marks of a good code is that you&#38;#39;re aware of what can change and what will not.&lt;/p&gt;

&lt;p&gt;For example some things are destined to change:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$mince_pies_eaten&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;$mince_pies_eaten&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;comment&#34;&gt;# yum!&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$mince_pies_eaten&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;comment&#34;&gt;# yum! yum!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And some things are not:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$WISE_MEN&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#38;#39;s good practice for your language to prevent you altering constants. Ideally if you accidentally did:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;symbol&#34;&gt;$WISE_MEN&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;/pre&gt;

&lt;p&gt;You&#38;#39;d want Perl to throw an exception. And you can easily make Perl do that with a little help from a module on the CPAN:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Const::Fast&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;const&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$WISE_MEN&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&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;There are $WISE_MEN wise men&#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;symbol&#34;&gt;$WISE_MEN&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;/pre&gt;

&lt;p&gt;Results in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    There are 3 wise men
    Modification of a read-only value attempted at - line 7.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;const&lt;/code&gt; keyword preceding the &lt;code&gt;my&lt;/code&gt; causes the &lt;i&gt;variable&lt;/i&gt; that &lt;code&gt;my&lt;/code&gt; refers to to be marked read-only and causes perl to throw a run-time exception if anything tries to alter it.&lt;/p&gt;

&lt;h2 id=&#34;Other-constant-techniques-that-dont-work-as-well&#34;&gt;Other constant techniques that don&#38;#39;t work as well&lt;/h2&gt;

&lt;p&gt;There have been several techniques for constants in Perl that you might have heard of, and it&#38;#39;s probably best to understand why we shouldn&#38;#39;t use them in modern, well maintained code.&lt;/p&gt;

&lt;h3 id=&#34;The-Inlined-Subroutine-Trick&#34;&gt;The Inlined Subroutine Trick&lt;/h3&gt;

&lt;p&gt;If you write a subroutine that returns a simple value:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE_MEN&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then that subroutine will be &lt;i&gt;inlined&lt;/i&gt; when perl compiles your code. This means that:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Lingua::EN::Numbers::Ordinate&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( ordinate )&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;WISE_MEN&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&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;structure&#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;word&#34;&gt;WISE_MEN&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;say&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Getting gift from &#38;quot;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;ordinate&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;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot; wise man&#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;/pre&gt;

&lt;p&gt;Doesn&#38;#39;t end up calling &lt;code&gt;WISE_MEN&lt;/code&gt; from the Perl statement at all - perl is clever enough to substitute a scalar for &lt;code&gt;3&lt;/code&gt; directly into the compiled op code removing the subroutine call at all. Let&#38;#39;s run it through the compiler/decompiler to see the code equivalent to what perl sees once everything has been compiled:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ perl -Mfeature=say -MO=Deparse script.pl
    sub WISE_MEN () {
        3;
    }
    use Lingua::EN::Numbers::Ordinate (&#38;#39;ordinate&#38;#39;);
    use feature &#38;#39;say&#38;#39;;
    foreach $_ (1 .. 3) {
        say &#38;#39;Getting gift from &#38;#39; . &#38;amp;ordinate($_) . &#38;#39; wise man&#38;#39;;
    }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;WISE_MEN&lt;/code&gt; in the for loop has gone!&lt;/p&gt;

&lt;p&gt;This &lt;i&gt;seems&lt;/i&gt; ideal, but there are some big problems:&lt;/p&gt;

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

&lt;p&gt;In order that I can write &lt;code&gt;WISE_MEN&lt;/code&gt; not &lt;code&gt;WISE_MEN()&lt;/code&gt; I need to declare the subroutine with a prototype, i.e. I need to write:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE_MEN&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;()&lt;/code&gt; indicates that no arguments are needed and the call to the subroutine can be written without brackets. However, this syntax is incompatible with the new experimental subroutine signatures feature recent versions of perl offer. Once enabled the same syntax would introduce run-time parameter checking and would result in a bare call to &lt;code&gt;WISE_MEN&lt;/code&gt; without the trailing brackets causing an exception. Our subroutine instead would have to be written as:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE_MEN&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;attribute&#34;&gt;prototype()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is even less readable than before.&lt;/p&gt;

&lt;h4 id=&#34;Only-Simple-Things&#34;&gt;Only Simple Things&lt;/h4&gt;

&lt;p&gt;Consider this misguided attempt to create &lt;i&gt;constants&lt;/i&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Lingua::EN::Numbers::Ordinate&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;ordinate&#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;MONTH_OF_XMAS&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;25&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;comment&#34;&gt;# 25th&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DATE_OF_XMAS&lt;/span&gt;&lt;span class=&#34;prototype&#34;&gt;()&lt;/span&gt;  &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;12&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;comment&#34;&gt;# 12th&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;On the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;DATE_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; day of the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;MONTH_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; month...&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The value isn&#38;#39;t simple enough and perl won&#38;#39;t inline it, meaning that not only does our constant result in a subroutine call each time it&#38;#39;s called, but it also that results in a call to &lt;code&gt;ordinate&lt;/code&gt; each time.&lt;/p&gt;

&lt;h3 id=&#34;Using-use-constant&#34;&gt;Using &lt;code&gt;use constant&lt;/code&gt;;&lt;/h3&gt;

&lt;p&gt;The solution to each of these is to use a core module called &lt;code&gt;constant&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Lingua::EN::Numbers::Ordinate&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;ordinate&#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;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;constant&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;MONTH_OF_XMAS&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;25&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;constant&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;DATE_OF_XMAS&lt;/span&gt;  &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;ordinate&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;number&#34;&gt;12&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;print&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;On the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;DATE_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; day of the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;MONTH_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; month...&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This declaration creates a simple subroutine that returns whatever value you passed to the call to &lt;code&gt;use constant&lt;/code&gt;. Running this through the parser/deparser shows us that things have been helpfully simplified:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    shell$ perl -MO=Deparse script.pl
    use Lingua::EN::Numbers::Ordinate (&#38;#39;ordinate&#38;#39;);
    use constant (&#38;#39;MONTH_OF_XMAS&#38;#39;, &#38;amp;ordinate(25));
    use constant (&#38;#39;DATE_OF_XMAS&#38;#39;, &#38;amp;ordinate(12));
    print &#38;#39;On the 12th day of the 25th month...&#38;#39;;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, there&#38;#39;s a couple of problems with this technique&lt;/p&gt;

&lt;h4 id=&#34;No-interpolation&#34;&gt;No interpolation&lt;/h4&gt;

&lt;p&gt;Ideally instead of writing:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;On the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;DATE_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; day of the &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;MONTH_OF_XMAS&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; month...&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&#38;#39;d love it if we could just write:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;On the $DATE_OF_XMAS day of the $MONTH_OF_XMAS month...&#39;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;Doesnt-Play-Nice-With-Hash-Keys&#34;&gt;Doesn&#38;#39;t Play Nice With Hash Keys&lt;/h4&gt;

&lt;p&gt;Worse, these constants can&#38;#39;t be used in situations where Perl would normally automatically quote values for you.&lt;/p&gt;

&lt;p&gt;Consider this code:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;constant&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE1&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Melchior&#39;&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;constant&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE2&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Caspar&#39;&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;constant&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;WISE3&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Balthazar&#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%gifts&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;WISE1&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Gold&#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;WISE2&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Frankenstein&#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;WISE3&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Muwhur?&#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;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gifts&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;Balthazar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;};&lt;/span&gt;  &lt;span class=&#34;comment&#34;&gt;# doesn&#39;t work as we&#39;d expect&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The fat comma (aka the &lt;code&gt;=&#38;gt;&lt;/code&gt;) causes WISE1 to be the literal string &lt;code&gt;WISE1&lt;/code&gt; not &lt;code&gt;Melchior&lt;/code&gt; as we&#38;#39;d expected. We need to write this as:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;%gifts&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;WISE1&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;single&#34;&gt;&#39;Gold&#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;WISE2&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;single&#34;&gt;&#39;Frankenstein&#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;WISE3&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;single&#34;&gt;&#39;Muwhur?&#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;/code&gt;&lt;/pre&gt;

&lt;p&gt;The same is true for the hash keys.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# WRONG&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$ag&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gifts&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;WISE1&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;# RIGHT&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$shelly&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$gifts&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;WISE2&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;()};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;Const::Fast-is...fast&#34;&gt;Const::Fast is...fast.&lt;/h2&gt;

&lt;p&gt;Const::Fast relies on perl&#38;#39;s in-build internal read-only support to make normal variables read-only. This means a variable that Const::Fast has marked as a constant can still be used just like any other variable - interpolated into strings, used as hash keys - except it cannot be altered because it has the read-only flag set.&lt;/p&gt;

&lt;p&gt;This read-only functionality isn&#38;#39;t provided by Const::Fast - it&#38;#39;s just using the same mechanism perl uses internally to stop you altering literals in your source code. For example consider what happens if you write a subroutine that alters its arguments but instead of passing in a variable you pass in a literal string:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;shorten&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;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;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;substitute&#34;&gt;s/Christmas/Xmas/&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;comment&#34;&gt;# this works fine&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;my&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;single&#34;&gt;&#39;Merry Christmas&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;shorten&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$string&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 gives the error&lt;br /&gt;# Modification of a read-only value attempted at - line 4.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;shorten&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Merry Christmas&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Internally perl uses the same sort of representation for the variable &lt;code&gt;$string&lt;/code&gt; and the literal string we&#38;#39;re passing to &lt;code&gt;shorten&lt;/code&gt;, but the latter has a flag set on it to mark it as read only. Const::Fast enables the same flag on variables that you create with &lt;code&gt;const&lt;/code&gt; meaning this acts in the same way:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;# this also gives the error&lt;br /&gt;# Modification of a read-only value attempted at - line 4.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$string&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Merry Christmas&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;shorten&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$string&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This means that constants defined by Const::Fast have no run-time penalty and are as fast as hard-coding the value in all the places you use the constant. Awesome!&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-08T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Choices, choices, so many choices!</title><link href="http://perladvent.org/2017/2017-12-07.html"/><id>http://perladvent.org/2017/2017-12-07.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Every day we have to tell our computers about the hundreds of choices we make each day. Yes, I&#38;#39;d like to get the blue scarf, not the green one. Change into this directory not that one. Please force push those changes all over that branch. Yes, of course I&#38;#39;m sure!&lt;/p&gt;

&lt;p&gt;Being the command line geeks we are, most of the time this comes in the form of passing arguments to command line programs. Passing option flags. Setting enviroment variables before we run the script. All of these things are awesome. We can script them. There&#38;#39;s command history. We can use command line tab completion (if we&#38;#39;ve setup bash or zsh just right.)&lt;/p&gt;

&lt;p&gt;But sometimes this can get complex. Maybe as users we don&#38;#39;t (or can&#38;#39;t) know what all the options are without starting to run the script. Maybe we need to be presented with more choices depending on some of the choices we&#38;#39;ve already made. Maybe the program needs to ask the user something after it&#38;#39;s done something with a remote server, and there was no way to predict what questions it needed to have the answer for when the program was originally run. Or maybe we just want something more user friendly than forcing the user to look up in the man page what options they need to pass.&lt;/p&gt;

&lt;p&gt;In these situations we tend to build an interactive GUI app or a web app. However, both of these are much harder to do than writing a program tha parses simple commmand line options - there&#38;#39;s event loops to consider, callbacks, possibly listening on various ports. Maybe there&#38;#39;s a better, er, &lt;i&gt;choice&lt;/i&gt;.&lt;/p&gt;

&lt;h3 id=&#34;Introducting-Term::Choose&#34;&gt;Introducting Term::Choose&lt;/h3&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/module/Term::Choose&#34;&gt;Term::Choose&lt;/a&gt; is a module that allows us to interactively pick from the terminal from several options. It&#38;#39;s &lt;i&gt;really&lt;/i&gt; simple to use:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Term::Choose&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( choose )&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;$reindeer&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;choose&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;words&#34;&gt;qw(&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Ruldolph&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Dasher Dancer Prancer Vixen&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Comet Cupid Dunder Blixem&lt;br /&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;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Who is your favourite reindeer?&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;exit&lt;/span&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;double&#34;&gt;&#38;quot;Cool I like $reindeer too!&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;chooser.gif&#34; width=&#34;678&#34; height=&#34;177&#34; alt=&#34;Terminal demo&#34;&gt;

&lt;/p&gt;



&lt;p&gt;The user simply moves the selection around with the cursor keys and hits &lt;code&gt;RETURN&lt;/code&gt; to pick one. Easy!&lt;/p&gt;

&lt;p&gt;Coding this is considerably more simple than developing a GUI or web app, and because it&#38;#39;s running on a terminal you can make use of it anywhere - even on a remote server you&#38;#39;re connected to over ssh wihtout the overhead and the complexity of doing something tricky with an X-server.&lt;/p&gt;

&lt;p&gt;Note also that Term::Choose is a good terminal citizen. It cleans up after itself, removing the interactive prompt from the screen.&lt;/p&gt;

&lt;h3 id=&#34;More-options-than-fit-on-the-screen&#34;&gt;More options than fit on the screen&lt;/h3&gt;

&lt;p&gt;If you have more options than fit on the screen then the screen scrolls when you move down past the last option:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Term::Choose&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( choose )&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;$film&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;choose&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;cast&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;@films&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;What Christmas movie shall I rent?&#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;br /&gt;&lt;span class=&#34;structure&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;exit&lt;/span&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;double&#34;&gt;&#38;quot;Renting $film&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;choosef.gif&#34; width=&#34;678&#34; height=&#34;177&#34; alt=&#34;Terminal demo&#34;&gt;

&lt;/p&gt;



&lt;p&gt;Neat! You really don&#38;#39;t have to think about it.&lt;/p&gt;

&lt;h3 id=&#34;Picking-More-Than-One-Option&#34;&gt;Picking More Than One Option&lt;/h3&gt;

&lt;p&gt;If you use the &lt;code&gt;choose&lt;/code&gt; function in list context you can pick more than one option. Just hitting &lt;code&gt;RETURN&lt;/code&gt; works as before, picking just the one option. However, hitting &lt;code&gt;SPACE&lt;/code&gt; selects multiple options, and then &lt;code&gt;RETURN&lt;/code&gt; submits them all.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Term::Choose&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( choose )&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;@options&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;choose&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;single&#34;&gt;&#39;with wrapping paper&#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;single&#34;&gt;&#39;with a bow on it&#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;single&#34;&gt;&#39;with ribbons&#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;single&#34;&gt;&#39;with a gift tag&#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;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;How should I wrap up the present?&#39;&lt;/span&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;double&#34;&gt;&#38;quot;Wrapping up the present with $_&#38;quot;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@options&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;choosew.gif&#34; width=&#34;678&#34; height=&#34;177&#34; alt=&#34;Terminal demo&#34;&gt;

&lt;/p&gt;



&lt;h3 id=&#34;The-Right-Choice&#34;&gt;The Right Choice&lt;/h3&gt;

&lt;p&gt;Like all my favourite Perl modules, Term::Choose is powerful but simple to use. It does one thing, and does it well. It&#38;#39;s the right choice.&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-07T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>North Pole Safety Precautions</title><link href="http://perladvent.org/2017/2017-12-06.html"/><id>http://perladvent.org/2017/2017-12-06.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;The Wise Old Elf was pair programming with Noel Cuddlecrackers, one of the newer elves to join Santa&#38;#39;s merry little band of programmers.&lt;/p&gt;

&lt;p&gt;Noel and he had agreed to start work on a really simple script. Noel opened a new file, and the Wise Old Elf watched patiently as Noel typed:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Pretty good&#38;quot;, the Wise Old Elf thought to himself, &#38;quot;at least he&#38;#39;s enabling strictures to help catch mistakes&#38;quot;. Noel kept typing though...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;no&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;indirect&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Excellent, Noel&#38;#39;s not allowing calls of the form &lt;code&gt;new Foo&lt;/code&gt;&#38;quot; the elder Elf thought to himself. But Noel wasn&#38;#39;t done typing...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;no&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;multidimensional&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Okay, so Noel&#38;#39;s disabling Perl&#38;#39;s problematic multi-dimensional array syntax that no-one uses since we use arrays containing references to arrays these days&#38;quot; the Wise old Elf considered. But Noel still was typing more things...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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(:all)&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Now he&#38;#39;s avoiding to have to manually check each time if one of Perl&#38;#39;s IO routines succeeded, and just have them automatically throw an exception&#38;quot;. Noel was &lt;b&gt;still&lt;/b&gt; typing...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;utf8&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;So he&#38;#39;s allowing utf-8 encoding in the document so he can type non-ascii characters directly into the source&#38;quot; the Wise Old Elf mused.&lt;/p&gt;

&lt;p&gt;Noel was still typing. The Wise Old Elf had to stop him before he became the Wise Much Older Elf.&lt;/p&gt;

&lt;p&gt;&#38;quot;Noel&#38;quot;, he asked, &#38;quot;exactly how much more boilerplate stuff are you going to type before we get to work?&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;Not much&#38;quot;, the young faced worker replied, with a big grin on his face, &#38;quot;I just have to enable a few experimental features, monkey around with the method resolution order, and...&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;STOP&#38;quot;, the Wise Old Elf firmly interrupted. &#38;quot;You do realize that we have a standard module that we use for our in house stuff that does all of this for us, don&#38;#39;t you?&#38;quot; Indeed, it was true. A few years back the Wise Old Elf had monkeyed around with a Perl module called &lt;code&gt;Import::Into&lt;/code&gt; that allowed a module to import modules into whoever used that module. This allowed the Wise Old Elf to create a standard boilerplate module that they now imported at the start of every Perl source file. Near the top of each file there simply was the line&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NorthPole::Ourperl&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And all the source code that Cuddlecrackers wrote (and was going to add) could be replaced. &lt;code&gt;Import::Into&lt;/code&gt; is simple to use - you simply call the fully qualified method &lt;code&gt;import::into&lt;/code&gt; on the package name you want to import into whoever uses your module inside the &lt;code&gt;import&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NorthPole::Ourperl&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;br /&gt;&lt;br /&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;&lt;span class=&#34;comment&#34;&gt;    # turn on &#39;use strict&#39; in whoever does &#39;use NorthPole::Ourperl&#39;&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;word&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&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;operator&#34;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The full package that the North Pole is currently using looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;comment&#34;&gt;## no critic (NamingConventions::Capitalization)&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;NorthPole::Ourperl&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;## use critic (NamingConventions::Capitalization)&lt;br /&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;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;our&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;single&#34;&gt;&#39;1.000000&#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;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Import::Into&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;# XXX - it&#39;d be nice to include bareword::filehandles but this conflicts with&lt;br /&gt;# autodie - see https://rt.cpan.org/Ticket/Display.html?id=93591&lt;br /&gt;&lt;/span&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;float&#34;&gt;2.25&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;IPC::System::Simple&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;    &lt;span class=&#34;comment&#34;&gt;# to fatalize system&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;experimental&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;feature&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;indirect&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;mro&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;multidimensional&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 adds the UTF-8 layer on STDIN, STDOUT, STDERR for _everyone_&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;open&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( :encoding(UTF-8) :std )&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;utf8&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;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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&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;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;strict&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$caller_level&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;warnings&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$caller_level&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@experiments&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw(&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;lexical_subs&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;postderef&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;signatures&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;)&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;experimental&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;@experiments&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;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$version&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;$^V&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=~&lt;/span&gt; &lt;span class=&#34;match&#34;&gt;/^v(5\.\d+)/&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;feature&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&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;$version&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;    ## no critic (Subroutines::ProhibitCallsToUnexportedSubs)&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;word&#34;&gt;mro::set_mro&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;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;c3&#39;&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;comment&#34;&gt;    ## use critic&lt;br /&gt;&lt;/span&gt;    &lt;span class=&#34;word&#34;&gt;utf8&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$caller_level&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;indirect&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;unimport::out_of&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;:fatal&#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;multidimensional&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;unimport::out_of&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$caller_level&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;single&#34;&gt;&#39;open&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;:encoding(UTF-8)&#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;autodie&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;import::into&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$caller_level&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&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;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;/pre&gt;

&lt;p&gt;This:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Enables &lt;code&gt;strict&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Enables &lt;code&gt;warnings&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Turns on the experimental lexical subs feature&lt;/li&gt;
    &lt;li&gt;Turns on the experimental postfix derefencing feature&lt;/li&gt;
    &lt;li&gt;Turns on the experimental signature feature&lt;/li&gt;
    &lt;li&gt;Turns on whatever standard features this version of Perl supports (e.g. say, etc)&lt;/li&gt;
    &lt;li&gt;Sets the method resolution in the module to be &lt;code&gt;c3&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Disables indirect method calls&lt;/li&gt;
    &lt;li&gt;Disables old-style multidimensional array simulation&lt;/li&gt;
    &lt;li&gt;Configures the filehandles to be UTF-8 everwhere&lt;/li&gt;
    &lt;li&gt;Enables autodie for all system calls&lt;/li&gt;
    &lt;/ul&gt;

&lt;p&gt;In one line!&lt;/p&gt;

&lt;small&gt;Above source code example adapted from &lt;a href=&#34;https://metacpan.org/pod/App::GHPT::Wrapper::Ourperl&#34;&gt;App::GHPT::Wrapper::Ourperl&lt;/a&gt;, Copyright (c) 2017 by MaxMind, Inc, licensed under the The Artistic License 2.0.&lt;/small&gt;

&lt;/div&gt;</summary><updated>2017-12-06T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Santa Baby(cart)</title><link href="http://perladvent.org/2017/2017-12-05.html"/><id>http://perladvent.org/2017/2017-12-05.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;Pinecone Candypears was one of the Elves that the Wise Old Elf had wisely brought on to help with the JavaScript toolchain that was becoming an integral part of the new modern North Pole Intranet software. Pinecone wasn&#38;#39;t producing the kind of JavaScript the Wise old elf had started out with back in the day with ye olde &lt;code&gt;onclick&lt;/code&gt; handlers; Oh no, this modern JavaScript was a serious programming.&lt;/p&gt;

&lt;p&gt;&#38;quot;You see&#38;quot;, Pinecone was elaborating, &#38;quot;these days in our stack we program in ES6 - modern JavaScript - that&#38;#39;s cross compiled with these yarn plugins to turn it into more compatible JavaScript that your dumb browser can run. This allows us to do some pretty funky stuff.&#38;quot;&lt;/p&gt;

&lt;p&gt;Just to demonstrate Pinecone typed some code into his editor and hit save:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    const countMessage = `There are {presents} left in the sack`&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the background &lt;code&gt;yarn&lt;/code&gt; noticed the file was changed and produced a file that worked in the browser.&lt;/p&gt;

&lt;p&gt;&#38;quot;Don&#38;#39;t you see&#38;quot;, Pinecone continued gleefully, &#38;quot;with the new backtick string notation we can stick variables directly into our strings.&#38;quot;&lt;/p&gt;

&lt;p&gt;&#38;quot;You&#38;#39;ve been able to do that since forever in Perl just with doublequotes&#38;quot;, the wise old Elf smiled.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are $presents left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Ah&#38;quot;, Pinecone countered, &#38;quot;but what about a method call?&#38;quot;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    const countMessage = `There are { sack.presents() } left in the sack`&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;Well, that&#38;#39;s a little different&#38;quot;, the Wise Old Elf admitted, &#38;quot;But there is a way&#38;quot;&lt;/p&gt;

&lt;h3 id=&#34;Introducing-the-Babycart-Operator&#34;&gt;Introducing the Babycart Operator&lt;/h3&gt;

&lt;p&gt;In Perl it&#38;#39;s possible to put executable code directly in the middle of strings with something we like to call the &#38;quot;babycart operator&#38;quot;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are @{[ $sack-&#38;gt;presents ]} left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The babycart operator was &lt;a href=&#34;https://youtu.be/3SfEsW16sAg?t=577&#34;&gt;named&lt;/a&gt; by Philippe Bruhat (BooK) after a series of &lt;a href=&#34;http://www.imdb.com/title/tt0068816/&#34;&gt;Japanese films&lt;/a&gt; featuring Samurai and babycarts - the code you&#38;#39;re sticking in your string is inside the babycart!&lt;/p&gt;

&lt;center&gt;&lt;img src=&#34;babycart.jpg&#34; width=&#34;600&#34; height=&#34;350&#34; alt=&#34;BooK presenting&#34;&gt;&lt;/center&gt;

&lt;p&gt;It&#38;#39;s not really an operator at all, but some clever abuse of several existing operators to get what we want. Consider first of all what happens to arrays that are placed in the middle of strings:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;6&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;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are @count left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All the elements of the array are stringified and interpolated into the string. Since there&#38;#39;s only one thing in the array, the string above gets turned into &lt;code&gt;There are 6 left in the sack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what if we use an array reference instead, and use the &lt;code&gt;@{ ... }&lt;/code&gt; operator to dereference it?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;number&#34;&gt;6&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;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are @{ $count } left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hey, that still works! Let&#38;#39;s put the logic inside the anonymous array:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;structure&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$sack&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;presents&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;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are @{ $count } left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now finally let&#38;#39;s move that logic inside string:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;There are @{[ $sack-&#38;gt;presents ]} left in the sack&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;But-Where-Is-This-Useful&#34;&gt;But Where Is This Useful?&lt;/h3&gt;

&lt;p&gt;Even the Wise Old Elf wouldn&#38;#39;t recommend using it in the above situation. It&#38;#39;s probably better to just write:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$count_message&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;There are &#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$sack&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;presents&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39; left in the sack&#39;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But consider the heredoc where you can&#38;#39;t just do that:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;find_records_over&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$min&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;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;database_handle&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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;selectall_arrayref&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;heredoc&#34;&gt;&#38;lt;&#38;lt;~&#38;quot;SQL&#38;quot;&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;operator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$min&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;       SELECT id, @{[ $self-&#38;gt;fieldname ]}&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;FROM @{[ $self-&#38;gt;tablename ]}&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;WHERE @{[ $self-&#38;gt;fieldname ]} = ?&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;    SQL&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;</summary><updated>2017-12-05T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Here(doc) it is Merry Christmas</title><link href="http://perladvent.org/2017/2017-12-04.html"/><id>http://perladvent.org/2017/2017-12-04.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;The Wise Old Elf was doing code review for Sloeberry Snoozyflakes, one of the newest elves on his team.&lt;/p&gt;

&lt;p&gt;Slowberry was writing a simple routine to count the number of nice children there were this year, in order to get an estimate of the number of presents that Santa would need to deliver.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt; = &lt;span class=&#34;synConstant&#34;&gt;&#38;quot;SELECT count(*)&lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;&#38;quot;&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;synConstant&#34;&gt;&#38;quot;  FROM children&lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;&#38;quot;&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;synConstant&#34;&gt;&#38;quot;  WHER naughty_or_nice = &lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;\$&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;1&#38;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt; = &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;-&#38;gt;database_handle;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt;-&#38;gt;selectall_arrayref(&lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;That multi-line sql assignment is a little hard to read.&#38;quot;, the Wise Old Elf commented. &#38;quot;Could we change it to make it cleaner?&#38;quot;&lt;/p&gt;

&lt;p&gt;Slowberry changed his code to use a heredoc:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt; = &lt;span class=&#34;synConstant&#34;&gt;&#38;lt;&#38;lt;END&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;       SELECT count(*)&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;         FROM children&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;         WHER naughty_or_nice = &lt;/span&gt;&lt;span class=&#34;synSpecial&#34;&gt;\$&lt;/span&gt;&lt;span class=&#34;synConstant&#34;&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;END&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt; = &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;-&#38;gt;database_handle;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt;-&#38;gt;selectall_arrayref(&lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;That&#38;#39;s better,&#38;quot; the elf continued, &#38;quot;but if you&#38;#39;d used &lt;code&gt;SQL&lt;/code&gt; as the heredoc deliminator rather than than &lt;code&gt;TEXT&lt;/code&gt;, then your editor would probably enable syntax highlighting, and you&#38;#39;d probably have noticed that you typo-ed &lt;code&gt;WHERE&lt;/code&gt;.&#38;quot;&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;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt; = &lt;span class=&#34;synConstant&#34;&gt;&#38;lt;&#38;lt;SQL&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;       SELECT&lt;/span&gt; count(*)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       FROM&lt;/span&gt; children&lt;br /&gt;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       WHERE&lt;/span&gt; naughty_or_nice = $&lt;span class=&#34;synConstant&#34;&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;SQL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt; = &lt;span class=&#34;synIdentifier&#34;&gt;$self-&#38;gt;database_handle&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh-&#38;gt;selectall_arrayref&lt;/span&gt;(&lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;&#38;quot;Not bad, but you probably should put single quotes around the first heredoc deliminator so you don&#38;#39;t have escape that &lt;code&gt;$&lt;/code&gt;. In fact you should always put &lt;code&gt;&#38;quot;&lt;/code&gt; or &lt;code&gt;&#38;#39;&lt;/code&gt; around the heredoc deliminator just to make it clear to whoever is reading your code what you actually meant.&#38;quot;&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;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt; = &lt;span class=&#34;synConstant&#34;&gt;&#38;lt;&#38;lt;&#39;SQL&#39;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;       SELECT&lt;/span&gt; count(*)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       FROM&lt;/span&gt; children&lt;br /&gt;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       WHERE&lt;/span&gt; naughty_or_nice = $&lt;span class=&#34;synConstant&#34;&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synConstant&#34;&gt;SQL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt; = &lt;span class=&#34;synIdentifier&#34;&gt;$self-&#38;gt;database_handle&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh-&#38;gt;selectall_arrayref&lt;/span&gt;(&lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;&#38;quot;Pretty good. The terminating heredoc deliminator looks weird all over there on the left hand side, not indented like the rest of the subroutine. We&#38;#39;re using Perl 5.26, so we can add a tilde in the heredoc syntax to allow us to indent.&#38;quot;&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;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt; = &#38;lt;&#38;lt;~&lt;span class=&#34;synConstant&#34;&gt;&#39;SQL&#39;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;       SELECT&lt;/span&gt; count(*)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       FROM&lt;/span&gt; children&lt;br /&gt;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       WHERE&lt;/span&gt; naughty_or_nice = $&lt;span class=&#34;synConstant&#34;&gt;1&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;SQL&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh&lt;/span&gt; = &lt;span class=&#34;synIdentifier&#34;&gt;$self-&#38;gt;database_handle&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$dbh-&#38;gt;selectall_arrayref&lt;/span&gt;(&lt;span class=&#34;synIdentifier&#34;&gt;$sql&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;&#38;quot;That&#38;#39;s awesome. Not that it matters here, but the way this works is that the same amount of whitespace that&#38;#39;s before the final heredoc terminator is stripped from the rest of the heredoc. Maybe now we could remove some of the variables?&#38;quot;&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;synStatement&#34;&gt;sub &lt;/span&gt;&lt;span class=&#34;synIdentifier&#34;&gt;number_of_children &lt;/span&gt;{&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self&lt;/span&gt;            = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt; = &lt;span class=&#34;synStatement&#34;&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;synIdentifier&#34;&gt;$self-&#38;gt;database_handle&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;&#38;nbsp;&#38;nbsp;-&#38;gt;selectall_arrayref(&#38;lt;&#38;lt;~&lt;span class=&#34;synConstant&#34;&gt;&#39;SQL&#39;&lt;/span&gt;,{},&lt;span class=&#34;synIdentifier&#34;&gt;$naughty_or_nice&lt;/span&gt;)-&#38;gt;[&lt;span class=&#34;synConstant&#34;&gt;0&lt;/span&gt;];&lt;br /&gt;&lt;span class=&#34;synStatement&#34;&gt;       SELECT&lt;/span&gt; count(*)&lt;br /&gt;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       FROM&lt;/span&gt; children&lt;br /&gt;&#38;nbsp;&lt;span class=&#34;synStatement&#34;&gt;       WHERE&lt;/span&gt; naughty_or_nice = $&lt;span class=&#34;synConstant&#34;&gt;1&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;SQL&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&#38;nbsp;&lt;/td&gt;&lt;/table&gt;

&lt;p&gt;&#38;quot;There we go. Now you just need to add some more tests - that broken &lt;code&gt;WHERE&lt;/code&gt; from earlier can&#38;#39;t have possibly been executed, otherwise we&#38;#39;d have seen a test failure - and we&#38;#39;re ready to ship...&#38;quot;&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-04T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Context Matters</title><link href="http://perladvent.org/2017/2017-12-03.html"/><id>http://perladvent.org/2017/2017-12-03.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;The Wise Old Elf was looking at a code snippet Garland Twinklecake had brought to him.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&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;comment&#34;&gt;# holds our DBIx::Class resultsets that can be used to get the&lt;br /&gt;# naughty or nice children one by one&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;has&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_result_sets&#39;&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&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;builder&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;_build_result_sets&#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;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;_build_result_sets&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$children&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;_schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;naughty&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rs&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;word&#34;&gt;naughty&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;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;nice&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$rs&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;word&#34;&gt;naughty&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;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;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;naughty_child&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;$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;&#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;_result_sets&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;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;nice_child&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;$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;&#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;_result_sets&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;span class=&#34;structure&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#38;quot;I just don&#38;#39;t understand why it doesn&#38;#39;t work.&#38;quot;, Garland complained, &#38;quot;it just freezes right up&#38;quot;.&lt;/p&gt;

&lt;p&gt;&#38;quot;Okay, okay&#38;quot;, the Wise Old Elf reassured, &#38;quot;we can get to the bottom of this. Just run the whole thing with the &lt;code&gt;DBIC_TRACE&lt;/code&gt; environment variable set to true. and DBIx::Class will spit out the SQL it&#38;#39;s doing to STDERR.&#38;quot;&lt;/p&gt;

&lt;p&gt;No sooner had Garland run the command again than he immediately saw the problem; Perl was trying to bring back every single child from the database, and, well, that was, as you might expect, taking some time.&lt;/p&gt;

&lt;p&gt;&#38;quot;I see what&#38;#39;s going on now. You&#38;#39;ve been bitten by using the &lt;code&gt;search&lt;/code&gt; method in list context&#38;quot;, the Wise Old Elf explained.&lt;/p&gt;

&lt;h3 id=&#34;Context-Matters&#34;&gt;Context Matters&lt;/h3&gt;

&lt;p&gt;One way that people (and elves) often get into trouble with Perl is forgetting that some functions and methods act differently when called in list or scalar context.&lt;/p&gt;

&lt;p&gt;For example, this code creates two results sets we can use later to request children one by one:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$naughty_result_set&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;&#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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&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;word&#34;&gt;naughty&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;br /&gt;&lt;br /&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$nice_result_set&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;&#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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&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;word&#34;&gt;naughty&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;structure&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works because &lt;code&gt;search&lt;/code&gt; is being called in scalar context both times, and when it&#38;#39;s called in scalar context we get back a resultset as the names of the variables indicate. At this point these two abstract resultsets represent sets of conditions that will be run against the database as soon as we call &lt;code&gt;first&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt;, etc on them or can be used to create further refined result sets by adding additional conditions with further calls to &lt;code&gt;search&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, this seemingly similar code does something dramatically different&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result_sets&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;naughty&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;nice&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;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;/pre&gt;

&lt;p&gt;While it looks like the &lt;code&gt;search&lt;/code&gt; method here should return one value each time it&#38;#39;s called to pair with &lt;code&gt;naughty&lt;/code&gt; and &lt;code&gt;nice&lt;/code&gt;, that&#38;#39;s not what happens. &lt;code&gt;search&lt;/code&gt; in list context actually returns all the results as a big list making &lt;code&gt;$result_sets&lt;/code&gt; huge and filled with nonsensical data rather than just the two key-value pairs we were expecting. In other situations this can result in security risks where keys and parameters become mismatched.&lt;/p&gt;

&lt;p&gt;One way to fix this is to force scalar context with the &lt;code&gt;scalar&lt;/code&gt; keyword:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result_sets&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;naughty&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;nice&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;scalar&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;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;/pre&gt;

&lt;p&gt;The better solution however, is to just call &lt;code&gt;search_rs&lt;/code&gt; instead of &lt;code&gt;search&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$result_sets&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;naughty&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search_rs&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;word&#34;&gt;nice&lt;/span&gt;    &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$schema&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;resultset&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;single&#34;&gt;&#39;Child&#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;search_rs&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;naughty&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;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;/pre&gt;

&lt;p&gt;&lt;code&gt;search_rs&lt;/code&gt; is exactly the same as &lt;code&gt;search&lt;/code&gt;, except it always returns a result set object even when called in list context.&lt;/p&gt;

&lt;h3 id=&#34;Writing-a-Perl-Critic-rule&#34;&gt;Writing a Perl Critic rule&lt;/h3&gt;

&lt;p&gt;After all this explanation, Garland was frustrated. &#38;quot;Okay, I give up. We should just &lt;b&gt;never&lt;/b&gt; call the &lt;code&gt;search&lt;/code&gt; method. We should &lt;b&gt;always&lt;/b&gt; use &lt;code&gt;search_rs&lt;/code&gt;&#38;quot;&lt;/p&gt;

&lt;p&gt;The Wise Old Elf agreed, and he had a plan. Rather than just updating the coding standards document, he made sure that no code in the repository contained calls to the &lt;code&gt;search&lt;/code&gt; method and made it impossible for new code to sneak in calls to &lt;code&gt;search&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How did he do that? Well, the test suite for the North Pole codebase uses Test::Perl::Critic to ensure that the code in the repo meets the Perl::Critic guidelines defined in the &lt;code&gt;.perlcriticrc&lt;/code&gt;. So all the Wise Old Elf had left to do was write a quick Perl::Critic rule that freaks out at any method call to &lt;code&gt;search&lt;/code&gt; that isn&#38;#39;t wrapped in a &lt;code&gt;no critic&lt;/code&gt; type declaration.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::Critic::Policy::NorthPole::ProhibitSearchMethod&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;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;br /&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Perl::Critic::Utils&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( :severities is_method_call )&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;base&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Perl::Critic::Policy&#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;default_severity&lt;/span&gt;     &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$SEVERITY_HIGHEST&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;default_themes&lt;/span&gt;       &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( northpole )&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;# Don&#39;t support any parameters in the config file&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;supported_parameters&lt;/span&gt; &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&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;&lt;span class=&#34;comment&#34;&gt;# only call &#39;violates&#39; for elements that are Words (this speeds things up)&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;applies_to&lt;/span&gt;           &lt;span class=&#34;structure&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;PPI::Token::Word&#39;&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;# examine each PPI::Token::Word in the source code, and violate if it&#39;s any&lt;br /&gt;# call to the method &#39;search&#39;&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;keyword&#34;&gt;sub&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;violates&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;$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;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$element&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;&lt;br /&gt;&#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;symbol&#34;&gt;$element&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;search&#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;keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;is_method_call&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$element&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;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;violation&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;Use of the search() method is prohibited&#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;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;heredoc&#34;&gt;&#38;lt;&#38;lt;&#39;END&#39;&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;heredoc_content&#34;&gt;DBIx::Class&#39;s search() method returns a result set object in scalar context, but&lt;br /&gt;returns a list of results in list context.  This is unsafe when such a call is&lt;br /&gt;used in a constructor as it can mix up the parameter keys and values.  For&lt;br /&gt;example, if search returns no results this:&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;Foo::Bar-&#38;gt;new(&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;foo =&#38;gt; $schema-&#38;gt;resultset(&#39;Foo&#39;)-&#38;gt;search(...),&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;bar =&#38;gt; $user_value,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;baz =&#38;gt; $user_value2,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;...&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;);&lt;br /&gt;&lt;br /&gt;Could be interpreted as&lt;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;Foo::Bar-&#38;gt;new(&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;foo =&#38;gt; &#39;bar&#39;,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;$user_value =&#38;gt; baz,&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;$user_value2 =&#38;gt; ...&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;);&lt;br /&gt;&lt;br /&gt;This critic rule can easily have false positives if other classes have a&lt;br /&gt;C&#38;lt;search&#38;gt; method - we can&#39;t tell the difference with simple static analysis.&lt;br /&gt;&lt;/span&gt;&lt;span class=&#34;heredoc_terminator&#34;&gt;END&lt;br /&gt;&lt;/span&gt;        &lt;span class=&#34;symbol&#34;&gt;$element&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;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;/pre&gt;

&lt;/div&gt;</summary><updated>2017-12-03T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Around the world with Emoji</title><link href="http://perladvent.org/2017/2017-12-02.html"/><id>http://perladvent.org/2017/2017-12-02.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;It was the night before the night before Christmas and, as one of the best programmers on the rapid response team, Sherry Silversparkles was in a rush. She&#38;#39;d been handed the task of automating the updating of Santa&#38;#39;s twitter account as he travelled around the world. The kind of updates she&#38;#39;d been asked to post were really simple, as was the code she&#38;#39;d hastily written to do so.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Net::Twitter&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;Country::Codes&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( country )&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;tweet&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;$country_code&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;&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;$country&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;country&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;symbol&#34;&gt;$country_code&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;operator&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;die&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;Unknown country!&#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;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;keyword&#34;&gt;my&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$twitter&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Net::Twitter&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;username&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&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;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;password&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$pass&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;source&lt;/span&gt;   &lt;span class=&#34;operator&#34;&gt;=&#38;gt;&lt;/span&gt; &lt;span class=&#34;single&#34;&gt;&#39;Santa Twitteromatic Two Thousand&#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;br /&gt;&lt;br /&gt;&#38;nbsp;&#38;nbsp;&#38;nbsp;&#38;nbsp;&lt;span class=&#34;symbol&#34;&gt;$twitter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;double&#34;&gt;&#38;quot;Father Christmas&#39;s sleigh is flying to $country&#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;keyword&#34;&gt;return&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;/pre&gt;

&lt;p&gt;She submitted her work for acceptance by Elf command. However, within minutes she&#38;#39;d got a report back on the contents of her messages: tl;dr. Apparently today&#38;#39;s youths wouldn&#38;#39;t read more than a couple of words before getting bored and going back to checking Instagram. Elf command had suggested a three glyph alternative message:&lt;/p&gt;

&lt;center&gt;&lt;font size=&#34;48&#34;&gt;&#38;#127877;&#38;rarr;&#38;#127482;&#38;#127480;&lt;/font&gt;&lt;/center&gt;

&lt;p&gt;&#38;quot;Nothing like changing the specs at the last minute&#38;quot; Sherry mused to herself. Now she&#38;#39;d have to work out how to do these changes in a jiffy! Sherry already knew how to render the emoji for Santa and that right arrow:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\N{FATHER CHRISTMAS}\N{RIGHTWARDS ARROW}&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But as hard as she looked in her unicode charts, she couldn&#38;#39;t find the character for the US flag, nor for any of the other countries.&lt;/p&gt;

&lt;p&gt;After much head scratching, and a relaxing glass of mulled wine, Sherry discovered that not all glyphs in Unicode are represented by a single character. Some glyphs are made up by combining one or more characters:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\N{REGIONAL INDICATOR SYMBOL LETTER U}&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\N{REGIONAL INDICATOR SYMBOL LETTER S}&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On systems that don&#38;#39;t understand how to render flags that would simply display as an odd looking &lt;code&gt;U&lt;/code&gt; followed by an odd looking &lt;code&gt;S&lt;/code&gt; (which hopefully the end user would know as the ISO 3166-1 code for the United States). On more capable systems that would be turned into a United States flag emoji.&lt;/p&gt;

&lt;p&gt;So, that was simple - sort of - but Sherry still needed some way to turn the country code that her subroutine was being passed into those corresponding regional indicator characters. Of course, this being Perl, there was a module for that on the CPAN:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;Emoji::NationalFlag&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( code2flag )&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;br /&gt;&lt;br /&gt;&lt;span class=&#34;symbol&#34;&gt;$twitter&lt;/span&gt;&lt;span class=&#34;operator&#34;&gt;-&#38;gt;&lt;/span&gt;&lt;span class=&#34;word&#34;&gt;update&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;double&#34;&gt;&#38;quot;\N{FATHER CHRISTMAS}\N{RIGHTWARDS ARROW}&#38;quot;&lt;/span&gt; &lt;span class=&#34;operator&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;word&#34;&gt;code2flag&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;symbol&#34;&gt;$country_code&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;/pre&gt;

&lt;p&gt;This time Sherry&#38;#39;s changes were accepted, leaving her free to move onto the next last-minute Christmas programming panic...&lt;/p&gt;

&lt;/div&gt;</summary><updated>2017-12-02T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry><entry><title>Emoji</title><link href="http://perladvent.org/2017/2017-12-01.html"/><id>http://perladvent.org/2017/2017-12-01.html</id><summary type="html">&lt;div class=&#39;pod&#39;&gt;&lt;p&gt;One of the great things about the Wise Old Elf&#38;#39;s job was that he got to keep up with all the latest fads the kids were up to. He fondly remembered the hula-hoop craze. Micromachines. Pogs. Oh the memories!&lt;/p&gt;

&lt;p&gt;Today&#38;#39;s modern day kids are all about text messages. But not just any old text in their text messages. No, these kids are all about the Emojis. And honestly, how could anyone at the North Pole not love Emojis too? After all, Santa has his &lt;b&gt;very own emoji&lt;/b&gt;: Character 127877 in Unicode &lt;code&gt;FATHER CHRISTMAS&lt;/code&gt;.&lt;/p&gt;

&lt;center&gt;&lt;font size=&#34;48&#34;&gt;&#38;#127877;&lt;/font&gt;&lt;/center&gt;

&lt;p&gt;The Wise Old Elf was working on Perl script to generate text messages to all the elves telling them what a good job they were doing this year. And, of course, this would include the Father Christmas emoji.&lt;/p&gt;

&lt;p&gt;The first thing the Wise Old Elf did was universally enable UTF-8 encoding on STDOUT, STDIN, and STDERR with an &lt;code&gt;open&lt;/code&gt; pragma:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;open&lt;/span&gt; &lt;span class=&#34;words&#34;&gt;qw( :encoding(UTF-8) :std )&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when he printed out his emoji Perl would be outputting the byte sequence necessary to represent that emoji in UTF-8 and (hopefully) the other end would be able to recognize the code for Santa and Do The Right Thing.&lt;/p&gt;

&lt;p&gt;He then simply printed out the message he wanted, using the hexadecimal code for &lt;code&gt;127877&lt;/code&gt;, &lt;code&gt;1F385&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\x{1F385} thanks you for all your hard work tonight&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No sooner had he typed this then he started to have second thoughts. &lt;code&gt;\x{1F385}&lt;/code&gt; isn&#38;#39;t exactly the most instantly recognizable code. What if he had accidentally typed &lt;code&gt;\x{1F383}&lt;/code&gt; by mistake, the Unicode character for the jack-o-lantern. What a Nightmare Before Christmas situation that would be!&lt;/p&gt;

&lt;p&gt;Of course, the Wise Old Elf was using a modern editor which would be happy to edit utf-8 encoded source code, so he could simply enable UTF-8 source code in Perl too by declaring:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;keyword&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;pragma&#34;&gt;utf8&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At the top of the source code, and then he&#38;#39;d be able to simply 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;/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;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;&#38;#127877; thanks you for all your hard work tonight&#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;Was he done? He wasn&#38;#39;t so sure.&lt;/p&gt;

&lt;p&gt;Typing this would this either involve some crazy keyboard shenanigans to type, or he&#38;#39;d have to copy-and-paste from a Unicode pallet. It wasn&#38;#39;t the best situation, but he could put up with that.&lt;/p&gt;

&lt;p&gt;The main problem was that the Wise Old Elf was Old enough (and Wise enough) to know that not all editors support UTF-8 source code and all it&#38;#39;ll take is one Elf using an editor doing the wrong thing with encodings to potentially break everything. The last thing the Wise Old Elf needed was to post a message of thanks for a bunch of unrenderable character sequences instead of the man in the red suit.&lt;/p&gt;

&lt;p&gt;Luckily Perl is able to represent all Unicode characters in a simple, readable, ASCII encodable way: You can use the &lt;code&gt;\N{...}&lt;/code&gt; sequence with the official name of the character:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;code-listing&#34;&gt;&lt;span class=&#34;word&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;double&#34;&gt;&#38;quot;\N{FATHER CHRISTMAS} thanks you for all your hard work tonight&#38;quot;&lt;/span&gt;&lt;span class=&#34;structure&#34;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;</summary><updated>2017-12-01T00:00:00Z</updated><category term="Perl"/><author><name>Mark Fowler</name></author></entry></feed>