<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Articles on Perl.com - programming news, code and culture</title>
    <link>https://www.perl.com/article/</link>
    <description>Recent content in Articles on Perl.com - programming news, code and culture</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 11 Nov 2020 11:04:40 +0000</lastBuildDate>
    <atom:link href="/article/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Bang Bang</title>
      <link>https://www.perl.com/article/bang-bang/</link>
      <pubDate>Wed, 11 Nov 2020 11:04:40 +0000</pubDate>
      
      <guid>https://www.perl.com/article/bang-bang/</guid>
      <description>

&lt;p&gt;&lt;img src=&#34;https://www.perl.com/images/bang-bang/blackmagic.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;Interpreters read and execute scripts (whereas shells are more like a kitchen pass-through and can either execute or hand over to another interpreter). When we specify interpreter on the command line, it is the one that will be used. For instance &lt;code&gt;Rscript script.R&lt;/code&gt; will execute &lt;em&gt;script.R&lt;/em&gt; using the &lt;code&gt;Rscript&lt;/code&gt; interpreter.&lt;/p&gt;

&lt;p&gt;When we execute a file without explicitly giving an interpreter (for instance, like &lt;code&gt;./myscript.pl&lt;/code&gt;), it is the job of the &amp;ldquo;shebang&amp;rdquo; to tell to the shell/OS which interpreter to use. The shebang is that first line of a text file that starts with &lt;code&gt;#!&lt;/code&gt; and is followed by the interpreter path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sometimes we see the &lt;code&gt;env&lt;/code&gt; program, which finds the the first &lt;code&gt;perl&lt;/code&gt; in our path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env perl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;env&lt;/code&gt; does not split args therefore we can&amp;rsquo;t add options:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#!/usr/bin/env perl -w&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And, &lt;code&gt;env&lt;/code&gt; is not always located in &lt;code&gt;/usr/bin/env&lt;/code&gt; so it can guarantee some portability at machine/distribution level but not always between distributions.&lt;/p&gt;

&lt;h2 id=&#34;perl-is-nice&#34;&gt;Perl is nice&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;perl&lt;/code&gt; is not like other interpreters—its nice, even with challenges. &lt;code&gt;perl&lt;/code&gt; inspects the shebang to check if it&amp;rsquo;s really for it (and if not it hands our program over to another interpreter).&lt;/p&gt;

&lt;p&gt;For instance the file &lt;em&gt;i-am-python.pl&lt;/em&gt; contains a Python program, which is definitely not Perl:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/python&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; os
&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#39;m a snake : &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;environ[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;SHELL&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;environ[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;_&amp;#34;&lt;/span&gt;])

&lt;span style=&#34;color:#75715e&#34;&gt;# Keep it alive to have time to inspect with ps&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; True:
    time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obviously we don&amp;rsquo;t care about the extension as it does not mean any kind of file association (although some systems let you associate it). So we have a &lt;em&gt;.pl&lt;/em&gt; file and we execute it with &lt;code&gt;perl&lt;/code&gt; but inside we have a &lt;code&gt;python&lt;/code&gt; shebang and some python code. It&amp;rsquo;s clearly not a valid Perl file.&lt;/p&gt;

&lt;p&gt;If you don&amp;rsquo;t believe me, check this with a quick syntax check &lt;code&gt;perl -c i-am-python.pl&lt;/code&gt; that tells us it isn&amp;rsquo;t valid Perl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl -c i-am-python.pl
syntax error at i-am-python.pl line 3, near &amp;quot;import time&amp;quot;
i-am-python.pl had compilation errors.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we execute this file with perl, surprisingly, everything goes fine. How did that happen? &lt;code&gt;perl&lt;/code&gt; is smart enough to give the script to &lt;code&gt;python&lt;/code&gt;!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl i-am-python.pl
I&#39;m a snake : /bin/bash /usr/bin/perl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if we want to check which interpreter really runs this script, we can look in the process table:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ps aux | grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;i-am-pytho[n].pl&amp;#34;&lt;/span&gt;
tduponc+  &lt;span style=&#34;color:#ae81ff&#34;&gt;5647&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.0  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.0  &lt;span style=&#34;color:#ae81ff&#34;&gt;33208&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;7024&lt;/span&gt; pts/0    S    &lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt;:04   &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;:00 /usr/bin/python i-am-python.pl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that &lt;code&gt;i-am-pytho[n].pl&lt;/code&gt; with the brackets, which puts the &lt;code&gt;n&lt;/code&gt; in a character class. That&amp;rsquo;s a nifty trick so &lt;code&gt;grep&lt;/code&gt; finds the line with &lt;code&gt;python&lt;/code&gt; but not the &lt;code&gt;grep&lt;/code&gt; process itself because that pattern won&amp;rsquo;t match a literal &lt;code&gt;[&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t forget to kill the program since it&amp;rsquo;s sleeping forever!&lt;/p&gt;

&lt;p&gt;Now, what if we want to test the converse and run Perl code with a &lt;code&gt;python&lt;/code&gt; interpreter?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#39;m a jewel&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$str : $ENV{SHELL} $ENV{_}\n&amp;#34;&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) { sleep &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;; }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a valid Perl file but the &lt;code&gt;python&lt;/code&gt; interpreter does not hand over to &lt;code&gt;perl&lt;/code&gt; and just returns a Python error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ python i-am-perl.py
  File &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;iamperl.py&amp;#34;&lt;/span&gt;, line &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
    my $str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#39;m a jewel&amp;#34;&lt;/span&gt;;
       ^
SyntaxError: invalid syntax&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is special to Python. Try it yourself with bash, Ruby, or something else.&lt;/p&gt;

&lt;h2 id=&#34;i-have-something-for-you&#34;&gt;I have something for you&lt;/h2&gt;

&lt;p&gt;Having the correct interpreter on the command line does not mean that the shebang is totally ignored. &lt;code&gt;perl&lt;/code&gt; is once again super smart and behaves exactly as we can imagine (DWIM). For instance, what if we put a warning switch (&lt;code&gt;-w&lt;/code&gt;) in the shebang, like in this file &lt;em&gt;override-bang.pl&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl -w&lt;/span&gt;

$str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;will produce a warning&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though we don&amp;rsquo;t put the &lt;code&gt;-w&lt;/code&gt; on the command line, we still get warnings:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ perl override-bang.pl
Name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main::str&amp;#34;&lt;/span&gt; used only once: possible typo at override-bang.pl line &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;plenty-is-no-plague&#34;&gt;Plenty is no plague&lt;/h2&gt;

&lt;p&gt;Now, what if we specify some switches on the command line and some others in the shebang? &lt;strong&gt;SPOILER&lt;/strong&gt;: they are simply merged together.&lt;/p&gt;

&lt;p&gt;When we run &lt;code&gt;perl -c overridebang.pl&lt;/code&gt; to check a syntactically-valid file, we get the switches from the command line and the shebang line. We get a &lt;code&gt;perl -cw&lt;/code&gt; execution:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main::str&amp;#34;&lt;/span&gt; used only once: possible typo at override-bang.pl line &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;.
override-bang.pl syntax OK&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What if we have conflicting options like &lt;code&gt;-w&lt;/code&gt; to enable warnings and &lt;code&gt;-X&lt;/code&gt; to disable them? Here&amp;rsquo;s &lt;em&gt;enable-warnings.pl&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl -w&lt;/span&gt;

$str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;will produce a warning&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we run this on its own, we get a warning as expected:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl enable-warnings.pl
Name &amp;quot;main::str&amp;quot; used only once: possible typo at warnings.pl line 3.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we add &lt;code&gt;-X&lt;/code&gt; on the command line, there is no output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl -X enable-warnings.pl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How about the other way around with &lt;code&gt;-X&lt;/code&gt; on the shebang? Here&amp;rsquo;s &lt;em&gt;disable-warnings.pl&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl -X&lt;/span&gt;

$str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;will produce a warning&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we run this with &lt;code&gt;-w&lt;/code&gt;, we still don&amp;rsquo;t get output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl -X enable-warnings.pl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-X&lt;/code&gt; always turns off warnings.&lt;/p&gt;

&lt;p&gt;The shebang (&lt;code&gt;-X&lt;/code&gt;) is taken in priority versus the command line and no warning is reported. It&amp;rsquo;s the same if we execute the file with &lt;code&gt;perl -W disable-warnings.pl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could imagine that&amp;rsquo;s a rule to resolve conflicts with &amp;ldquo;last seen&amp;rdquo; parameter but wait, it&amp;rsquo;s not that simple.&lt;/p&gt;

&lt;p&gt;How about &lt;code&gt;-X&lt;/code&gt; versus &lt;code&gt;-W&lt;/code&gt;, which enables all warnings? Who wins then? It turns out that the last on defined wins. We can see that right on the command line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ perl -W -X -e &#39;$str = &amp;quot;will produce a warning&amp;quot;&#39;
$ perl -X -W -e &#39;$str = &amp;quot;will produce a warning&amp;quot;&#39;
Name &amp;quot;main::str&amp;quot; used only once: possible typo at -e line 1.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As an exercise for the reader, try the different combinations of taint checking options: &lt;code&gt;-T&lt;/code&gt; and &lt;code&gt;-U&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;a-magic-incantation&#34;&gt;A magic incantation&lt;/h2&gt;

&lt;p&gt;Sometimes we see some odd lines at the beginning of Perl programs. What the hell is this black magic? This is actually very smart opening is &amp;ldquo;polyglot&amp;rdquo; and correct for both shells (with or without shebang support) and &lt;code&gt;perl&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
eval &#39;exec /usr/bin/perl -S $0 ${1+&amp;quot;$@&amp;quot;}&#39;
    if $running_under_some_shell;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we start the script with &lt;code&gt;perl&lt;/code&gt;, the job is done and &lt;code&gt;perl&lt;/code&gt; executes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;eval &#39;exec /usr/bin/perl -S $0 ${1+&amp;quot;$@&amp;quot;}&#39;
if $running_under_some_shell;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That &lt;code&gt;$running_under_some_shell&lt;/code&gt; has no value, so the code translate to a false conditional. This line is ignored and the rest of the file is interpreted normally.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;eval &#39;exec /usr/bin/perl -S $0 ${1+&amp;quot;$@&amp;quot;} if 0;&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What if we start the script with a shell that recognizes the shebang? The shell does the handover to &lt;code&gt;perl&lt;/code&gt;, which then reads the first line (shebang then &lt;code&gt;eval ...&lt;/code&gt;). The execution flow is then the same than above (magic incantation does nothing and file is interpreted). Nothing surprising there.&lt;/p&gt;

&lt;p&gt;But what if we started the script with a shell that does not recognize the shebang so no handover occurs right away? This is actually where this magic is useful. The shell will ignore first line and will never reach third line. Why will it never reach third line? A newline terminates the shell command and &lt;code&gt;exec&lt;/code&gt; will replace the current execution by &lt;code&gt;perl&lt;/code&gt;. The rest of the script doesn&amp;rsquo;t matter after that &lt;code&gt;exec&lt;/code&gt;. Our code changes from this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
eval &#39;exec /usr/bin/perl -S $0 ${1+&amp;quot;$@&amp;quot;}&#39;
    if $running_under_some_shell;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to effectively this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;eval &#39;exec /usr/bin/perl -S $0 ${1+&amp;quot;$@&amp;quot;}&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Those &lt;code&gt;$0&lt;/code&gt; and &lt;code&gt;$@&lt;/code&gt; are shell words for the script name and arguments
and the &lt;code&gt;-S&lt;/code&gt; tells &lt;code&gt;perl&lt;/code&gt; look for the value in &lt;code&gt;$0&lt;/code&gt; using PATH environment variable. (&lt;a href=&#34;https://perldoc.perl.org/perlrun.html#Command-Switches&#34;&gt;perldoc&lt;/a&gt;)&lt;/p&gt;

&lt;h2 id=&#34;x-is-fun&#34;&gt;-x is fun&lt;/h2&gt;

&lt;p&gt;We&amp;rsquo;ve had fun with the &lt;code&gt;perl&lt;/code&gt; interpreter and the shebang, but &lt;code&gt;perl&lt;/code&gt; has a &lt;code&gt;-x&lt;/code&gt; which is already fun by design. This option tells Perl that the program to execute is actually embedded in a larger chunk of unrelated text to ignore. Perhaps the Perl program is in the middle of an email message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;quot;I do not know if it is what you want, but it is what you get.
        -- Larry Wall&amp;quot;

#!/usr/bin/env perl

print &amp;quot;perl -x ignores everything before shebang\n&amp;quot;;
print &amp;lt;DATA&amp;gt;;

__END__

&amp;quot;Fortunately, it is easier to keep an old interpreter around than an
old computer.
        -- Larry Wall&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Executing this as a program is a syntax error because the Larry Wall quote before the shebang is not valid Perl. When we execute this code with &lt;code&gt;perl -x&lt;/code&gt;, everything before the shebang is ignored and it works:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ perl -x email.txt
perl -x ignores everything before shebang

&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Fortunately, it is easier to keep an old interpreter around than an
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;old computer.
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        -- Larry Wall&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Out of curiosity, what if we tried to go one step further? How about multiple shebangs in a file, where one of them has a &lt;code&gt;-x&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl -x&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But it only produces an error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Can&#39;t emulate -x on #! line.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is however a trick to achieve this, by using shell &lt;code&gt;eval&lt;/code&gt;. That &lt;code&gt;perl -x&lt;/code&gt; is now executed in a shell process and not interpreted by perl binary like previously.:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh&lt;/span&gt;
eval &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;exec perl -x $0 ${1+&amp;#34;$@&amp;#34;}&amp;#39;&lt;/span&gt;
die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;another day&amp;#34;&lt;/span&gt;; exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#!perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$]\n&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;startperl&#34;&gt;startperl&lt;/h2&gt;

&lt;p&gt;This article would not be complete without discussing a bit about the config variable &lt;code&gt;$Config{startperl}&lt;/code&gt;. This variable comes from &lt;em&gt;Config.pm&lt;/em&gt;  that provides information about configuration environment (which you also see with &lt;code&gt;perl -V&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ perl -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;use Config; print $Config{startperl}&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is actually built during compilation from defaults or user/vendor provided configs. What if we want a different value? Simply specify the value of this during the &lt;code&gt;./Configure&lt;/code&gt; step, the configure option is &lt;code&gt;-Dstartperl=&#39;...&#39;&lt;/code&gt;. We then need to rebuild &lt;code&gt;perl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ./Configure -des -Dstartperl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;#!/my/shebang&amp;#39;&lt;/span&gt;
$ make test install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now our custom value is the default:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ perl -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;use Config; print $Config{startperl}&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#!/my/shebang&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&#34;https://metacpan.org/pod/ExtUtils::MakeMaker&#34;&gt;ExtUtils::MakeMaker&lt;/a&gt; and &lt;a href=&#34;https://metacpan.org/pod/Module::Build&#34;&gt;Module::Build&lt;/a&gt; seems also to use &lt;code&gt;startperl&lt;/code&gt; among other methods to fix modules shebangs.&lt;/p&gt;

&lt;p&gt;Take care to use an interpreter or a program that behaves like a &lt;code&gt;perl&lt;/code&gt; interpreter! Some CPAN modules use &lt;code&gt;startperl&lt;/code&gt; to write first line of generated perl tests. The &lt;code&gt;/usr/bin/env&lt;/code&gt; limitation still apply here.&lt;/p&gt;

&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://www.in-ulm.de/~mascheck/various/shebang/&#34;&gt;The #! magic, details about the shebang/hash-bang mechanism on various Unix flavours&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://unix.stackexchange.com/questions/29608/why-is-it-better-to-use-usr-bin-env-name-instead-of-path-to-name-as-my&#34;&gt;Why it is better to usr /usr/bin/env interpreter instead of /path/to/interpreter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://unix.stackexchange.com/questions/450509/could-someone-explain-this-shebang-line-which-uses-sh-and-then-does-exec-perl&#34;&gt;Could someone explain this shebang line which uses sh and then does exec perl?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;A tiny portion comes from &lt;a href=&#34;https://linuxfr.org/news/sortie-de-perl-5-30-0&#34;&gt;Sortie de Perl 5.30.0&lt;/a&gt; (en français).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Stupid DATA Tricks</title>
      <link>https://www.perl.com/article/stupid-data-tricks/</link>
      <pubDate>Mon, 05 Oct 2020 19:34:55 +0000</pubDate>
      
      <guid>https://www.perl.com/article/stupid-data-tricks/</guid>
      <description>

&lt;p&gt;&lt;em&gt;Image credit: &lt;a href=&#34;https://www.flickr.com/photos/rob_nguyen/4825313399/in/photolist-8moZyB-4F7P92-2a8nJsX-51pZVG-54XALL-EGpPw-APZM8-4rcAmM-4Fc3s3-2hZ4Rda-7bKxmy-4uifKZ-4uigsM-9hozPR-67hKJY-7PLYc4-4F7PtX-7vE59y-4uiHW6-4F7Qma-4CYoWA-4CU9hX-4CU9at-9944f3-nXDwwV-7mue3G-7XNVLz-2E9Zba-5XwYAf-HMZN7J-57WA3L-qDw1vt-afGkSG-hfdkf-azYcfR-hgnQe-4BmXTh-h7qCJ-hcCSS-uHxKGM-dfyF4a-8Hrqg5-pAsXDF-i5a6WK-8PmthW-EPp3X-roBDF-89oTap-8Hoi2v-9wSY7D&#34;&gt;Rob Nguyen on Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve previously written about &lt;a href=&#34;https://www.perl.com/article/182/2015/7/15/Stupid-open-tricks/&#34;&gt;Stupid Open Tricks&lt;/a&gt;, so now it&amp;rsquo;s time for some stupid &lt;code&gt;DATA&lt;/code&gt; tricks. You probably already know that you can &amp;ldquo;embed&amp;rdquo; a file inside a Perl program then read it from the &lt;code&gt;DATA&lt;/code&gt; filehandle. David Farrell wrote about this in &lt;a href=&#34;https://www.perl.com/article/24/2013/5/11/Perl-tokens-you-should-know/&#34;&gt;Perl tokens you should know&lt;/a&gt; and he&amp;rsquo;s the one who reminded me about the curiousity that I&amp;rsquo;ll demonstrate here.&lt;/p&gt;

&lt;p&gt;Anything after the &lt;code&gt;__DATA__&lt;/code&gt; line is not part of the program but is available to the program through the special &lt;code&gt;DATA&lt;/code&gt; filehandle:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
__DATA__
Dog
Cat
Bird&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows each line after &lt;code&gt;__DATA__&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
Dog
Cat
Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I typically go the other way by starting with a data file and adding a program to the top of it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; v5&lt;span style=&#34;color:#ae81ff&#34;&gt;.26&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Text::CSV_XS;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $csv &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Text::CSV_XS&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt;( &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $row &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $csv&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;getline(&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;DATA) ) {
	say join &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;, $row&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;@&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;[&lt;/span&gt;3,&lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;];
    }
close $fh;

__DATA__
&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;many CSV lines&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;this-is-the-end-my-friend-the-end&#34;&gt;This is the end, my friend, the &lt;strong&gt;END&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;You probably also know that you can use &lt;code&gt;__END__&lt;/code&gt; instead. I&amp;rsquo;m used to using that because it&amp;rsquo;s a holdover from Perl 4 and that&amp;rsquo;s where I first learned this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#75715e&#34;&gt;__END__
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Dog
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Cat
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Bird&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You get the same output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
Dog
Cat
Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But now let&amp;rsquo;s get a little tricky. Define a package at the end of the program. This still uses &lt;code&gt;__END__&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;package&lt;/span&gt; not::main;
&lt;span style=&#34;color:#75715e&#34;&gt;__END__
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Dog
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Cat
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Bird&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, this outputs the same thing as before. Nothing surprising here, but the suspense must be building:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
Dog
Cat
Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Change that &lt;code&gt;__END__&lt;/code&gt; to &lt;code&gt;__DATA__&lt;/code&gt; and try again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;package&lt;/span&gt; not::main;
__DATA__
Dog
Cat
Bird&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you don&amp;rsquo;t see those lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you&amp;rsquo;ve read the documentation and cared about this sort of thing (or like me, forgotten it), you may have noticed that the &lt;code&gt;DATA&lt;/code&gt; handle lives in the package that&amp;rsquo;s in scope at the end of the program:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Text after &lt;strong&gt;DATA&lt;/strong&gt; may be read via the filehandle &amp;ldquo;PACKNAME::DATA&amp;rdquo;, where &amp;ldquo;PACKNAME&amp;rdquo; is the package that was current when the &lt;strong&gt;DATA&lt;/strong&gt; token was encountered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can use the package specification to get the lines back:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;not::main::DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;package&lt;/span&gt; not::main;
__DATA__
Dog
Cat
Bird&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now those lines are back:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
Dog
Cat
Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But what about the &lt;code&gt;__END__&lt;/code&gt;? Well, that was a Perl 4 thing, before there were packages. Perl 5 added packages, then Perl 5.6 added the &lt;code&gt;__DATA__&lt;/code&gt; token. The &lt;code&gt;__END__&lt;/code&gt; kept doing what it was doing in the way it was doing it (package-less), and &lt;code&gt;__DATA__&lt;/code&gt; did something related by new:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For compatibility with older scripts written before &lt;strong&gt;DATA&lt;/strong&gt; was introduced, &lt;strong&gt;END&lt;/strong&gt; behaves like &lt;strong&gt;DATA&lt;/strong&gt; in the top level script (but not in files loaded with &amp;ldquo;require&amp;rdquo; or &amp;ldquo;do&amp;rdquo;) and leaves the remaining contents of the file accessible via &amp;ldquo;main::DATA&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;some-other-data-tricks&#34;&gt;Some other DATA tricks&lt;/h2&gt;

&lt;p&gt;There&amp;rsquo;s a few other interesting things you can do.&lt;/p&gt;

&lt;h3 id=&#34;program-size&#34;&gt;Program size&lt;/h3&gt;

&lt;p&gt;You can get the entire file size with the &lt;code&gt;-s&lt;/code&gt; file test operator. The &lt;code&gt;__DATA__&lt;/code&gt; (or &lt;code&gt;__END__&lt;/code&gt;) has to be there, but you don&amp;rsquo;t need any data after those tokens.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; v5&lt;span style=&#34;color:#ae81ff&#34;&gt;.10&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;s DATA;
say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;File size is $size&amp;#34;&lt;/span&gt;;
__DATA__&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The file size this reports includes everything in the file, not just the part before the end of processing.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; v5&lt;span style=&#34;color:#ae81ff&#34;&gt;.10&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;s DATA;
say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;File size is $size&amp;#34;&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tell DATA;
say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Data starts at $data&amp;#34;&lt;/span&gt;;
say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Data size is &amp;#34;&lt;/span&gt;, $size &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; $data
&lt;span style=&#34;color:#75715e&#34;&gt;__END__
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Dog
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Cat
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Bird&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The program size includes the &lt;code&gt;__END__&lt;/code&gt; token and the newline after it. The rest belongs to the data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;File size is 164
Data starts at 151
Data size is 13
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can use &lt;code&gt;DATA&lt;/code&gt; in other file things, including &lt;code&gt;stat&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&#34;read-it-twice&#34;&gt;Read it twice&lt;/h3&gt;

&lt;p&gt;If you want to read the data twice, you can reset the file cursor. First, remember where &lt;code&gt;DATA&lt;/code&gt; starts by calling &lt;code&gt;tell&lt;/code&gt; before you read any lines. When you are ready to read it again, &lt;code&gt;seek&lt;/code&gt; to that same position:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $data_start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tell DATA;

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;

seek DATA, $data_start, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#75715e&#34;&gt;__END__
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Dog
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Cat
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Bird&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;using-line-numbers&#34;&gt;Using line numbers&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $data_start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tell DATA;

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting DATA\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt;( &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt; ) {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$. $_&amp;#34;&lt;/span&gt;
	}
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;

&lt;span style=&#34;color:#75715e&#34;&gt;__END__
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Dog
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Cat
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;Bird&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you see some line numbers, but those start counting from the first line under &lt;code&gt;__DATA__&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
1 Dog
2 Cat
3 Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To get the real line numbers, you can figure out where the &lt;code&gt;__END__&lt;/code&gt; token is. This assumes that it&amp;rsquo;s not in the middle of documentation or in a string:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
my $data_start = tell DATA;

my $end_line;
UNITCHECK {
	open my $fh, &#39;&amp;lt;&#39;, $0;
	while( &amp;lt;$fh&amp;gt; ) { last if /\A__END__$/ }
	$end_line = $.
	}

print &amp;quot;---Outputting DATA\n&amp;quot;;
while( &amp;lt;DATA&amp;gt; ) {
	$n = $end_line + $.;
	print &amp;quot;$n $_&amp;quot;
	}
print &amp;quot;---Done\n&amp;quot;;

__END__
Dog
Cat
Bird
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you see the offsets in the whole file and not the count after the &lt;code&gt;__END__&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting DATA
19 Dog
20 Cat
21 Bird
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some more vigorous methods in &lt;a href=&#34;https://stackoverflow.com/q/55788554/2766176&#34;&gt;Can a Perl program know the line number where &lt;strong&gt;DATA&lt;/strong&gt; begins?
&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&#34;multiple-embedded-files&#34;&gt;Multiple embedded files&lt;/h3&gt;

&lt;p&gt;This isn&amp;rsquo;t a &lt;code&gt;DATA&lt;/code&gt; thing, but you can make several embedded files with &lt;a href=&#34;https://metacpan.org/pod/Inline::Files&#34;&gt;Inline::Files&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Inline::Files;

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting dogs\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DOGS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting cats\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;CATS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting birds\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;BIRDS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
__DOGS__
Rin Tin Tin
Lassie
Ol&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&amp;#39;&lt;/span&gt; Yellar
__CATS__
Grumpy Cat
Garfield
Maru
Mr Bigglesworth
__BIRDS__
Woody Woodpecker
Roadrunner
Zazu
Sam the Eagle&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each of those get their own filehandles:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---Outputting dogs
Rin Tin Tin
Lassie
Ol&#39; Yellar
---Done
---Outputting cats
Grumpy Cat
Garfield
Maru
Mr Bigglesworth
---Done
---Outputting birds
Woody Woodpecker
Roadrunner
Zazu
Sam the Eagle
---Done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&#34;https://metacpan.org/pod/Inline::Files&#34;&gt;Inline::Files&lt;/a&gt; has a problem because it overrides &lt;code&gt;open&lt;/code&gt;. You have to use &lt;code&gt;CORE::open&lt;/code&gt; to get to the real one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Inline::Files;

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting dogs\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;DOGS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting cats\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;CATS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting birds\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;BIRDS&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;

CORE::open &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $fh, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;:utf8&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/etc/hosts&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die $!;
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Outputting hosts\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;$fh&amp;gt;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;---Done\n&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>The Perl Ambassador: Damian Conway</title>
      <link>https://www.perl.com/article/the-perl-ambassador-damian-conway/</link>
      <pubDate>Thu, 01 Oct 2020 00:00:00 +0000</pubDate>
      
      <guid>https://www.perl.com/article/the-perl-ambassador-damian-conway/</guid>
      <description>

&lt;p&gt;This month I interview Damian Conway, one of the Guardians of Perl. Damian is computer scientist and excellent communicator—his presentations and courses are widely popular around the world. He was the Adjunct Associate Professor in the Faculty of Information Technology at Melbourne’s Monash University between 2001 and 2010.&lt;/p&gt;

&lt;p&gt;It was an honour to interview my idol. I enjoyed talking to him and I am sure you would have many &amp;ldquo;aha&amp;rdquo; moments. For example, Raku&amp;rsquo;s built-in grammar construct is inspired by the work of Damian&amp;rsquo;s &lt;a href=&#34;https://metacpan.org/pod/Parse::RecDescent&#34;&gt;Parse::RecDescent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also found out that Damian was the winner of Larry Wall Award for Practical Utility three years in a row from 1998 to 2000 for contributions to CPAN.&lt;/p&gt;

&lt;p&gt;He also wrote some of the most popular books on Perl:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.manning.com/books/object-oriented-perl&#34;&gt;Object Oriented Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.oreilly.com/library/view/perl-best-practices/0596001738/&#34;&gt;Perl Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.oreilly.com/library/view/perl-hacks/0596526741/&#34;&gt;Perl Hacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&amp;rsquo;d like me to interview you, or know someone you&amp;rsquo;d like me to interview, let me know. Take the same set of questions and send me your answers!&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;when-and-how-did-you-get-started-with-perl&#34;&gt;When and how did you get started with Perl?&lt;/h2&gt;

&lt;p&gt;In the mid-to-late 1990s, I was an academic at Australia&amp;rsquo;s largest university. At the time I was working on an unusually diverse range of research topics: educational technology, programming language design, software engineering, documentation systems, human-computer interaction, natural language generation, emergent systems, image morphing, human-computer interaction, API design, geometric modelling, the psychophysics of perception, nanoscale physical simulation, and parsing techniques. I liked to think I was a polymath, but the correct word is probably &amp;ldquo;dilettante&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Anyway, I was implementing most of my software in C++, and I desperately needed some other language (any other language!) that would make text manipulation and generation, interface design, and programming language research a great deal easier. In particular, I was trying to solve problems in natural-language text generation, and so I searched the infant internet for a programming platform that would make that task, if not easy, then at least not painful. During that search I found Perl.&lt;/p&gt;

&lt;p&gt;Within six months I had submitted two papers (on automating English inflexion, and on declarative command line interfaces) to the 2nd Perl Conference. Both were accepted and so I received funding from my institution to attend the conference. I don&amp;rsquo;t think I had been at the conference for more than half a day before I realized that I had finally found my tribe. And the rest is history.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-made-you-write-perl-best-practices&#34;&gt;What made you write &lt;em&gt;Perl Best Practices&lt;/em&gt;?&lt;/h2&gt;

&lt;p&gt;Mostly it was two of the three Perl virtues: Impatience and Hubris. In the early 2000s I was becoming extremely impatient with the prevailing view outside the Perl community that Perl was a &amp;ldquo;write-only&amp;rdquo; language that produced code which was impossible to read, understand or maintain. And I was equally impatient with the prevailing view inside the Perl community that &amp;ldquo;More Than One Way To Do It&amp;rdquo; was a licence (or possibly a challenge) to do it in the most terse, tricky, and obscure ways possible.&lt;/p&gt;

&lt;p&gt;Which led to hubris: the notion that I could find and teach a set of better habits for Perl coding; habits that would automatically produce code that was cleaner, more readable, more understandable, more robust, and more maintainable that the Perl code I was then seeing (well, to be honest, that I was then seeing mostly in my own terse, tricky, obscure module implementations).&lt;/p&gt;

&lt;p&gt;So I sat down and reviewed every line of Perl code I had ever written, and a great many lines of Perl code that others had written, trying to find patterns of coding that consistently led either to excellent or to terrible code. Within six months I had over 250 such observations, and started teaching them in a two-day class. Soon after that, O&amp;rsquo;Reilly got in touch and suggested they might make a good book.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;do-you-follow-your-own-suggestions-in-the-book&#34;&gt;Do you follow your own suggestions in the book?&lt;/h2&gt;

&lt;p&gt;Yes. I feel it would be highly hypocritical of me not to.&lt;/p&gt;

&lt;p&gt;However, I&amp;rsquo;ll admit that, at first, eating my own dog food was pure agony. A solid majority of my 250+ pieces of advice advised behaviours that I was not following myself at the time. I had to change just about everything from my curly-bracketing style (I was a confirmed &lt;a href=&#34;https://en.wikipedia.org/wiki/Indentation_style#Variant:_BSD_KNF&#34;&gt;BSD layout&lt;/a&gt; partisan, but &lt;em&gt;PBP&lt;/em&gt; advocates &lt;a href=&#34;https://en.wikipedia.org/wiki/Indentation_style#K&amp;amp;R_style&#34;&gt;K&amp;amp;R style&lt;/a&gt;), to my identifier-naming conventions (I originally didn&amp;rsquo;t have any at all, and was highly addicted to single-letter variables), to my commenting style (&amp;ldquo;Comments? My code is self-documenting!&amp;rdquo;), to the way I wrote OO Perl (usually without a framework, and always without proper encapsulation).&lt;/p&gt;

&lt;p&gt;It took me months to replace all my bad habits with better ones, and even longer to download those new habits into my fingertips, so that they &amp;ldquo;just happened&amp;rdquo; whenever I was typing in code. But it&amp;rsquo;s been so very worthwhile. I can clearly see the difference between my pre-&lt;em&gt;PBP&lt;/em&gt; code and the code I wrote after that time. I actually enjoy maintaining and improving the more recent code, whereas I find myself continually putting off any need to delve back into my older codebases.&lt;/p&gt;

&lt;p&gt;In several cases (for example, &lt;a href=&#34;https://metacpan.org/pod/Lingua::EN::Inflect&#34;&gt;Lingua::EN::Inflect&lt;/a&gt; or &lt;a href=&#34;https://metacpan.org/pod/IO::Prompt&#34;&gt;IO::Prompt&lt;/a&gt;) it was easier to completely rewrite the module (creating &lt;a href=&#34;https://metacpan.org/pod/Lingua::EN::Inflexion&#34;&gt;Lingua::EN::Inflexion&lt;/a&gt; and &lt;a href=&#34;https://metacpan.org/pod/IO::Prompter&#34;&gt;IO::Prompter&lt;/a&gt; respectively) rather than deal with that dreadful pre-&lt;em&gt;PBP&lt;/em&gt; code.&lt;/p&gt;

&lt;p&gt;Of course, there&amp;rsquo;s nothing intrinsically magical about the particular suggestions in the book. Indeed, in my current version of the class, somewhere around 20% of my advice has actually changed from what I wrote in &lt;em&gt;PBP&lt;/em&gt;. The magic is in adopting and practising any set of consistent, well-thought-out, and productive coding habits.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-do-you-think-about-perl-7-currently-being-discussed-widely&#34;&gt;What do you think about &amp;ldquo;Perl 7&amp;rdquo; currently being discussed widely?&lt;/h2&gt;

&lt;p&gt;I think it&amp;rsquo;s great to see Perl moving out from under the lingering ghost of &amp;ldquo;Perl 6&amp;rdquo;. And to see such a strong statement of positive forward motion, hopefully without too much of the attendant disruption of breaking vast swathes of existing code.&lt;/p&gt;

&lt;p&gt;And, more importantly, I think it&amp;rsquo;s vital that the widely accepted boilerplate components of a modern Perl program (&lt;code&gt;use strict&lt;/code&gt;, &lt;code&gt;use warnings&lt;/code&gt;, declarative subroutine parameters, postfix dereferencing) should be turned on by default under new versions of Perl. And, of course, that some of the especially problematic vestigial components (indirect-object method calls, implicit hash-key concatenation, bareword filehandles) should be deprecated with extreme prejudice.&lt;/p&gt;

&lt;p&gt;Of course, a plan this bold and this unanticipated will inevitably create anxiety and raise dissent. And not all those fears and disagreements will be misplaced. Even so, the very best thing about Perl 7 (whatever it ultimately proves to be) is that even just the idea of making a major version bump to usher in such fundamental changes is generating a huge amount of productive discussion and debate with the Perl community, and injecting a vast quantity of new energy, which must surely eventually lead to a better outcome, a better path forward for Perl.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;do-you-follow-the-development-of-cor&#34;&gt;Do you follow the development of &amp;ldquo;Cor&amp;rdquo;?&lt;/h2&gt;

&lt;p&gt;Yes, I&amp;rsquo;ve been following the Cor project with great interest for the past six months or so. I&amp;rsquo;ve occasionally also been consulting on the design of this proposed new mechanism, discussing particular issues and offering suggestions to Ovid on several aspects of the design. &lt;em&gt;(Editor: See our earlier &lt;a href=&#34;https://www.perl.com/article/the-perl-ambassador-curtis-poe/&#34;&gt;interview with Ovid&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Needless to say, I&amp;rsquo;m immensely excited by the prospect of having a genuinely declarative interface for class definitions added right into the core of the language! Even if that happy day is likely to be a few years away yet.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;you-have-loads-of-handy-modules-published-on-cpan-what-are-your-top-5-contributions-and-why&#34;&gt;You have loads of handy modules published on CPAN. What are your top 5 contributions and why?&lt;/h2&gt;

&lt;p&gt;In no particular order:&lt;/p&gt;

&lt;h3 id=&#34;lingua-en-inflexion&#34;&gt;Lingua::EN::Inflexion&lt;/h3&gt;

&lt;p&gt;This is the successor to my first ever public Perl module (&lt;a href=&#34;https://metacpan.org/pod/Lingua::EN::Inflect&#34;&gt;Lingua::EN::Inflect&lt;/a&gt;), which was one of the two modules I presented at my first ever Perl conference, and which therefore in a sense paved the way for all the others. Both the original and the successor modules attempt to solve the very challenging problem of producing and recognizing correct word inflections in English (&amp;ldquo;cat&amp;rdquo;→&amp;rdquo;cats&amp;rdquo;, &amp;ldquo;box&amp;rdquo;→&amp;rdquo;boxes&amp;rdquo;, &amp;ldquo;ox&amp;rdquo;→&amp;rdquo;oxen&amp;rdquo;, &amp;ldquo;fish&amp;rdquo;→&amp;rdquo;fish&amp;rdquo;, &amp;ldquo;goose&amp;rdquo;→&amp;rdquo;geese&amp;rdquo;, &amp;ldquo;maximum&amp;rdquo;→&amp;rdquo;maxima&amp;rdquo;, &amp;ldquo;penny&amp;rdquo;→&amp;rdquo;pennies&amp;rdquo;, etc. etc.)&lt;/p&gt;

&lt;p&gt;The reason I&amp;rsquo;m nominating the successor module instead of the original as one of my top five is that &lt;a href=&#34;https://metacpan.org/pod/Lingua::EN::Inflexion&#34;&gt;Lingua::EN::Inflexion&lt;/a&gt; is vastly more powerful, more reliable, and more maintainable, and reflects so much of what I have learned about the design and implementation of good APIs over the past two decades.&lt;/p&gt;

&lt;h3 id=&#34;parse-recdescent&#34;&gt;Parse::RecDescent&lt;/h3&gt;

&lt;p&gt;This was another early module, which provided what I like to think was the first truly Perlish grammatical parsing engine for the language. Prior to its release there had been ports of lex/yacc for Perl, but &lt;a href=&#34;https://metacpan.org/pod/Parse::RecDescent&#34;&gt;Parse::RecDescent&lt;/a&gt; allowed you to define grammars directly in your program, directly in Perl. It would also execute those grammars immediately, without a separate precompilation phase. The module has been very widely used over the past two decades in a huge number of commercial and academic projects. Finally, many of the ideas I pioneered in &lt;a href=&#34;https://metacpan.org/pod/Parse::RecDescent&#34;&gt;Parse::RecDescent&lt;/a&gt; eventually made their way into Raku&amp;rsquo;s built-in grammar construct, a contribution of which I&amp;rsquo;m immensely proud.&lt;/p&gt;

&lt;h3 id=&#34;quantum-superpositions&#34;&gt;Quantum::Superpositions&lt;/h3&gt;

&lt;p&gt;In a similar vein, I have a huge fondness for my &lt;a href=&#34;https://metacpan.org/pod/Quantum::Superpositions&#34;&gt;Quantum::Superpositions&lt;/a&gt; module. Not only because my presentation on that module has always been so hugely enjoyable to give, but also because that module led directly to the fundamental Raku concept of &amp;ldquo;junctions&amp;rdquo;, which I feel might be my only meaningful contribution to the field of computer science.&lt;/p&gt;

&lt;h3 id=&#34;regexp-debugger&#34;&gt;Regexp::Debugger&lt;/h3&gt;

&lt;p&gt;I use a great many regexes in my Perl solutions. When they go right, regexes are such powerful and efficient tools for solving complex data-processing problems, but when they go wrong, they&amp;rsquo;re an swirling abyss of confusion and frustration. That&amp;rsquo;s why I feel that &lt;a href=&#34;https://metacpan.org/pod/Regexp::Debugger&#34;&gt;Regexp::Debugger&lt;/a&gt; is probably the single most useful module I&amp;rsquo;ve ever written. It changes the task of debugging complex regexes from a multi-level, multi-day, multi-pain-killer nightmare into a simple, quick, &amp;ldquo;d&amp;rsquo;oh&amp;rdquo;-moment of sudden revelation. This module has saved me (and many other Perl users, I hope) literally thousands of hours of misery, simply by making our regex mistakes directly visible from right within the code itself.&lt;/p&gt;

&lt;h3 id=&#34;ppr&#34;&gt;PPR&lt;/h3&gt;

&lt;p&gt;Talking of complex regexes, I love the PPR module because it consists almost entirely of a single regex; a single 70000-character regex that can parse the vast majority of valid Perl documents. It&amp;rsquo;s such a mind-bogglingly simple and obvious idea; and yet it was so damn difficult to actually achieve. But worth every long hour of struggle. Having the ability to write a regex that matches a complete block of code, or a variable declaration, or a &amp;lsquo;for&amp;rsquo; loop, or a &amp;lsquo;use&amp;rsquo; statement, or any other Perl construct, opens up an entirely new universe of possibilities for validating, modifying, and refactoring Perl code. PPR is the basis for so many of the other CPAN modules of which I&amp;rsquo;m most proud, especially &lt;a href=&#34;https://metacpan.org/pod/Keyword::Declare&#34;&gt;Keyword::Declare&lt;/a&gt; (which allows you to safely extend the Perl syntax using Perl itself), Dios (which brings most of Raku&amp;rsquo;s vastly superior OO model and syntax to Perl), and &lt;a href=&#34;https://metacpan.org/pod/Code::ART&#34;&gt;Code::ART&lt;/a&gt; (which provides Perl-refactoring tools for the Vim editor).&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;you-visit-europe-regularly-and-give-lectures-on-perl-raku-related-topics-do-you-have-any-memorable-story-to-share&#34;&gt;You visit Europe regularly and give lectures on Perl/Raku related topics. Do you have any memorable story to share?&lt;/h2&gt;

&lt;p&gt;I think my most memorable single experience in Europe was lecturing on Raku (or, rather, on Perl 6, as it was back then) at CERN in Geneva in 2015.&lt;/p&gt;

&lt;p&gt;It was a pure joy to be in a room with so many brilliant people, talking with them about a project I have been so deeply committed to over the past two decades. And to watch that room full of brilliant people start to overcome their initial reluctance and begin to appreciate just how powerful this new language can be&amp;hellip;that was a great moment.&lt;/p&gt;

&lt;p&gt;Of course, it did require some chicanery to encourage them to put aside their scepticism and turn up in the first place. Specifically, I rearranged my standard talk so that I didn&amp;rsquo;t actually use the word &amp;ldquo;Perl&amp;rdquo; at all for nearly ninety minutes. In fact, I avoided naming the language in any way until the second-to-last slide.&lt;/p&gt;

&lt;p&gt;And, indeed, it was that particular experience–seeing how easy it was to sidestep the widespread general prejudice against anything related to &amp;ldquo;Perl&amp;rdquo;–that made me so very keen to support the name change from &amp;ldquo;Perl 6&amp;rdquo; to &amp;ldquo;Raku&amp;rdquo; last year.&lt;/p&gt;

&lt;p&gt;That visit to CERN was special to me for another reason too. Before my presentation, I had the privilege of being taken on a private tour of the facility. And though I didn&amp;rsquo;t manage to get down into the LHR itself (it was closed at the time for a refit), I did have my mind utterly blown by being allowed to wander around a building that seemed to be straight out of science fiction: the Antimatter Factory.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;you-briefly-blogged-about-the-weekly-challenge-how-did-you-find-about-it&#34;&gt;You briefly blogged about the weekly challenge, how did you find about it?&lt;/h2&gt;

&lt;p&gt;I learnt about the Weekly Challenge from the many blog posts from participants, which suddenly started popping up on my &lt;em&gt;blogs.perl.org&lt;/em&gt; and &lt;em&gt;reddit.com/r/perl+rakulang&lt;/em&gt; blog feeds. They seemed to be having so much fun that I couldn&amp;rsquo;t resist trying it myself.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;and-what-was-your-experience-with-it&#34;&gt;And what was your experience with it?&lt;/h2&gt;

&lt;p&gt;I loved taking part in it. Not just for the individual challenges it offered me, but also for the opportunities it gave me to showcase some of the power, expressiveness, and convenience of solving those puzzles in Raku. And in doing so to reach out beyond the Perl and Raku communities to briefly capture the attention of the wider developer world.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s well known how much I adore teaching, and the Weekly Challenge gave me yet another opportunity and outlet to indulge that passion.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;where-do-you-get-the-ideas-for-your-next-cpan-contributions&#34;&gt;Where do you get the ideas for your next CPAN contributions?&lt;/h2&gt;

&lt;p&gt;I think most of my ideas come directly from my extremely low threshold of annoyance. Whenever I am in the middle of trying to solve a particular problem in Perl, and I can&amp;rsquo;t find a sufficiently simple way of doing so, I frequently get quite unreasonably frustrated. And my immediate response is to ask myself: &amp;ldquo;If I could make this work any way I wanted, how would I make it work?&amp;rdquo;&lt;/p&gt;

&lt;p&gt;And then I remember that, being moderately competent in Perl, I can make it work in any way I want.  So I do.&lt;/p&gt;

&lt;p&gt;Mostly the actual ideas and solutions I implement come from a process I call &amp;ldquo;Design by Coding&amp;rdquo;. That is, when something is insufficiently easy, I just go ahead solve the problem the way I wish I could solve it, by writing the code that I wish I could write.&lt;/p&gt;

&lt;p&gt;Of course, that doesn&amp;rsquo;t actually solve the problem, because this &amp;ldquo;gedankencode&amp;rdquo; won&amp;rsquo;t actually run. But then I merely need to spend a ridiculous and completely unjustifiable amount of time and energy making the hypothetical code work in real life. Typically, far more time and energy than it would have taken to just do it the hard way.&lt;/p&gt;

&lt;p&gt;But the benefit is that, having expended all those hours on creating a better solution, thereafter I never have to do it the hard way again. And because I always put those solutions on CPAN, neither does anyone else.&lt;/p&gt;

&lt;p&gt;At a deeper level, I think I&amp;rsquo;ve been able to come up with so many unusual ideas in my career because I spend a great deal of time &amp;ldquo;filling the well&amp;rdquo;. My wife is an artist, and she introduced me to this concept: that in order to be creative, you have to constantly refill your mind with a large number of novel and random facts, observations, and ideas. Creativity is then the process of finding new and unexpected connections between those ideas. The more ideas you have, the more links you can easily find, so the more creative you can be.&lt;/p&gt;

&lt;p&gt;And that&amp;rsquo;s what I try to do. I try to read as diversely as I can, to give my creative processes the greatest possible range of building blocks and the greatest number of plausible (and implausible!) connections.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-would-you-suggest-to-someone-starting-perl&#34;&gt;What would you suggest to someone starting Perl?&lt;/h2&gt;

&lt;p&gt;Three things:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1. Write bad code.
2. Study better code.
3. Read great books.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I think the fundamental mistake most beginners make, however, is that they try to do those three things in the wrong order: books first, other people&amp;rsquo;s code next, writing their own code last.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t think there is any substitute for writing your own code from the very beginning. You need to grapple immediately with the challenges and puzzles of a new language. It&amp;rsquo;s the only way to actually improve as a programmer, especially in a language as eclectic and idiomatic as Perl.&lt;/p&gt;

&lt;p&gt;Only after you have struggled to write Perl yourself, you can start to appreciate the better code that others may have written. And once you can begin to recognize good Perl code, you can start to read productively about Perl, to learn why that code is good.&lt;/p&gt;

&lt;p&gt;Perl has so many great textbooks, but very few of them are completely sufficient  if you&amp;rsquo;re not already at least a little familiar with the language itself. Without that prior struggle, I don&amp;rsquo;t think you can genuinely appreciate the &amp;ldquo;aha!&amp;rdquo; moments, the sudden opportunities for deep understanding, that a truly excellent textbook will offer you.&lt;/p&gt;

&lt;p&gt;One other point I would make is that Perl almost suffers from a surfeit of excellent introductory textbooks&amp;hellip;which can make it difficult for any particular beginner to find the one best suited to their own background, their personal learning style, and their individual goals.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Learning Perl&lt;/em&gt; might be perfect for one person, but someone else might do much better with &lt;em&gt;Modern Perl&lt;/em&gt;. Some folks will find that a pragmatic use-case approach like &lt;em&gt;Impatient Perl&lt;/em&gt; best meets their needs, whereas others would be far better served by a text that&amp;rsquo;s at almost the opposite extreme, like the CS-based theoretical framework of &lt;em&gt;Elements of Programming with Perl&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The point is: if you&amp;rsquo;re looking for a book that will help you understand Perl, you should first try out at least a few of the many excellent alternatives available so you can find the one book that will help you understand Perl.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;i-noticed-you-are-associated-with-raku-these-days-do-you-still-use-perl&#34;&gt;I noticed you are associated with Raku these days. Do you still use Perl?&lt;/h2&gt;

&lt;p&gt;Almost every day. I love Raku dearly, and I&amp;rsquo;m starting to use it more and more often in my daily coding, but when I need to get something critical implemented ASAP and then have it run as fast as possible on as wide a range of platforms as possible, Perl is still the tool I reach for almost every time.&lt;/p&gt;

&lt;p&gt;For larger projects, Raku has some unbeatable advantages and in the next few years I expect its performance to become far more competitive, but for quick-and-dirty get-it-done-now tasks, Perl is still my preferred chainsaw.&lt;/p&gt;

&lt;p&gt;And I suspect it always will be.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Searching Internet RFCs</title>
      <link>https://www.perl.com/article/searching-internet-rfcs/</link>
      <pubDate>Thu, 24 Sep 2020 07:28:49 +0000</pubDate>
      
      <guid>https://www.perl.com/article/searching-internet-rfcs/</guid>
      <description>

&lt;p&gt;During the quarantine I was able to find the good side of the home confination: I hadn&amp;rsquo;t enough time to read a book due to school&amp;rsquo;s tests, but for my luck, I had enough time for reading one or two Request For Comments (RFC) documents.&lt;/p&gt;

&lt;p&gt;Since my first days studying computer security, the concept of &amp;ldquo;protocol&amp;rdquo; fascinated me. Maybe for their enormous diffusion in almost every computer system, our daily lives heavily depends from these processes. As I say &amp;ldquo;trust on machines but don&amp;rsquo;t trust humans&amp;rdquo;.
The RFC approach reminds the open source philosophy, which has the same objective (give everyone the opportunity to learn new things through sharing) and the same propagation channel: the internet.&lt;/p&gt;

&lt;p&gt;I find it too hard to search for these documents on &lt;a href=&#34;https://www.ietf.org&#34;&gt;the IETF website&lt;/a&gt;, so I made a fast and efficient script that permits me to download RFCs through a keyword and lets me decide which ones to read and which ones to ignore.&lt;/p&gt;

&lt;h2 id=&#34;what-are-rfcs&#34;&gt;What are RFCs?&lt;/h2&gt;

&lt;p&gt;&amp;ldquo;Request For Comments&amp;rdquo; are one of the best online references for learning how networking really works at the protocol level. These are simply text documents that define every single standard that has been approved by the Internet Engineering Task Force. These documents are a good entry point for developing the study of protocol analysis: an emerging field that uses formal verification to find exploits.&lt;/p&gt;

&lt;p&gt;Every RFC has a title and its associated number, for example the RFC 3607 is the &amp;ldquo;Chinese Lottery Cryptanalysis Revisited: The Internet as a Codebreaking Tool&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;My script uses &lt;a href=&#34;https://metacpan.org/pod/Net::RFC::Search&#34;&gt;Net::RFC::Search&lt;/a&gt; for the search, and &lt;a href=&#34;https://metacpan.org/pod/Term::ANSIColor&#34;&gt;Term::ANSIColor&lt;/a&gt; for the display—there will be a lot of text in the terminal and different coulrs can help!.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# Made by Edoardo Mantovani in 2020&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; strict;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; File::Path &lt;span style=&#34;color:#e6db74&#34;&gt;qw(make_path)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; File::Spec::Functions;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; LWP::Protocol::https; &lt;span style=&#34;color:#75715e&#34;&gt;# Net::RFC::Search needs this&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Net::RFC::Search;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Term::ANSIColor;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $folder &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; shift &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./RFC &amp;lt;Folder&amp;gt; &amp;lt;Query&amp;gt;\n&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $query  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; shift &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./RFC &amp;lt;Folder&amp;gt; &amp;lt;Query&amp;gt;\n&amp;#34;&lt;/span&gt;;

make_path $folder;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $rfc_interface &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Net::RFC::Search&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;();
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; @rfc_nums &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $rfc_interface&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;search_by_header( $query );

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;RFCs [@rfc_nums]\n&amp;#34;&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;foreach&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $rfc_num ( @rfc_nums ) {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $local_file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; catfile( $folder, $rfc_num ); &lt;span style=&#34;color:#75715e&#34;&gt;# i.e final folder = /tmp/1110&lt;/span&gt;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ( $rfc_interface&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;get_by_index( $rfc_num, $local_file ) ) {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; colored( &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Downloaded: $rfc_num\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;green&amp;#34;&lt;/span&gt; );
    view_rfc( $local_file );
  }
  &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error with RFC $rfc_num\n&amp;#34;&lt;/span&gt;;
  }
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;view_rfc&lt;/span&gt; {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt;( $file ) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; @_;

  open &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $fh, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;, $file &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; {
    warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Could not open file [$file]: $!\n&amp;#34;&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;;
  };

  &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt;( &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;$fh&amp;gt;&lt;/span&gt; ) {
  	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;;
  	&lt;span style=&#34;color:#66d9ef&#34;&gt;next&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;unless&lt;/span&gt; $. &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;25&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; colored(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Do you want to save this RFC? [Y/N] &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;red&amp;#34;&lt;/span&gt;);
    &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $input &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;STDIN&amp;gt;&lt;/span&gt;;
    chomp( $input );
	unlink $file &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; uc($input) &lt;span style=&#34;color:#f92672&#34;&gt;eq&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;N&amp;#34;&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;last&lt;/span&gt;;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Running the program requires a directory name and a query. I create the directory if it doesn&amp;rsquo;t already exist:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./rfc_search rfcs cookie
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I display the first 25 lines of each matching RFC and prompt to save it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.perl.com/images/searching_internet_rfcs/searching.gif&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;search_by_header&lt;/code&gt; returns the RFC numbers for each of the documents that has the query word:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; @rfc_nums &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; $rfc_interface&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;search_by_header( $query );&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I then fetch each document by specifying its number and local filename. I do this even if I won&amp;rsquo;t keep it because I don&amp;rsquo;t know what&amp;rsquo;s in it yet:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;$rfc_interface&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;get_by_index( $rfc_num, $local_file );&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For the last part, I look at the first 25 lines of the file. I have a prompt that asks me if I want to save it. If I enter &amp;ldquo;N&amp;rdquo;, I delete that file. I color the prompt so I can see it against the RFC text:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;view_rfc&lt;/span&gt; {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt;( $file ) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; @_;

  open &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $fh, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;, $file &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; {
    warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Could not open file [$file]: $!\n&amp;#34;&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;;
  };

  &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt;( &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;$fh&amp;gt;&lt;/span&gt; ) {
  	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;;
  	&lt;span style=&#34;color:#66d9ef&#34;&gt;next&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;unless&lt;/span&gt; $. &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;25&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; colored(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Do you want to save this RFC? [Y/N] &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;red&amp;#34;&lt;/span&gt;);
    &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $input &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;STDIN&amp;gt;&lt;/span&gt;;
    chomp( $input );
    rmtree(@_) &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; uc($input) &lt;span style=&#34;color:#f92672&#34;&gt;eq&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;N&amp;#34;&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;last&lt;/span&gt;;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;other-uses-and-suggestions&#34;&gt;Other uses and suggestions&lt;/h2&gt;

&lt;p&gt;I made this simple script mainly for save time and have a better interface for interacting with the RFC site, I want to recommend to see the TODO part in the &lt;a href=&#34;https://metacpan.org/pod/Net::RFC::Search&#34;&gt;Net::RFC::Search&lt;/a&gt; page. For a better script, it would be cool to implement &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;lynx&lt;/code&gt; to retrieve cancelled RFC&amp;rsquo;s. Of course the script can be implemented with custom functions but this is script is only for educational purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;resources&lt;/strong&gt;
- &lt;a href=&#34;https://blogs.helsinki.fi/mildred/2017/01/31/request-for-comments-user-stories-and-scenarios/&#34;&gt;Request for Comments: User Stories and Scenarios&lt;/a&gt;
- &lt;a href=&#34;https://en.wikipedia.org/wiki/Request_for_Comments&#34;&gt;Wikipedia&amp;rsquo;s RFC entry&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Perl Ambassador: Curtis &#39;Ovid&#39; Poe</title>
      <link>https://www.perl.com/article/the-perl-ambassador-curtis-poe/</link>
      <pubDate>Sat, 08 Aug 2020 04:40:00 +0000</pubDate>
      
      <guid>https://www.perl.com/article/the-perl-ambassador-curtis-poe/</guid>
      <description>

&lt;p&gt;This month&amp;rsquo;s interview is Curtis &amp;lsquo;Ovid&amp;rsquo; Poe, one of the most-respected and well-known leaders in the Perl community.&lt;/p&gt;

&lt;p&gt;Curtis has been building software for decades. He specializes in building database-driven websites through his global development and consulting firm, &lt;a href=&#34;https://allaroundtheworld.fr/&#34;&gt;All Around The World&lt;/a&gt;. He&amp;rsquo;s the main developer behind &lt;a href=&#34;https://taustation.space/&#34;&gt;Tau Station&lt;/a&gt;, a text-based Massive Multiplayer Online Browser Game (MMOBG) set in a vibrant, far-future universe.&lt;/p&gt;

&lt;p&gt;He&amp;rsquo;s the author of &lt;a href=&#34;https://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/&#34;&gt;Beginning Perl&lt;/a&gt; and &lt;a href=&#34;https://www.amazon.com/Perl-Hacks-Programming-Debugging-Surviving/dp/0596526741/&#34;&gt;Perl Hacks&lt;/a&gt;. You can out more about his activities at &lt;a href=&#34;https://ovid.github.io/&#34;&gt;https://ovid.github.io/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;He joined The Perl Foundation &lt;a href=&#34;https://news.perlfoundation.org/post/new_board_member&#34;&gt;boards of directors&lt;/a&gt; in 2009.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;d like me to interview you, or know someone you&amp;rsquo;d like me to interview, let me know. Take the same set of questions and send me your answers!&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;how-did-you-first-start-using-perl&#34;&gt;How did you first start using Perl?&lt;/h2&gt;

&lt;p&gt;I first started using Perl about 20 years ago, when I was doing mainframe programming. I was trying to fix a problem with a COBOL program that was converting a CSV file from an NT system to the fixed-width format that COBOL prefers. COBOL has many weaknesses and working with text is one of them. The code was 150 lines long, but that’s because the author didn’t understand how the COBOL’s unstring function worked. I got it down to 80 lines of COBOL. Out of curiosity, I tried it in Perl and got it down to 10 lines of code. Everything I touched in Perl was shorter and easier to read, so I jumped ship.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-do-you-think-about-perl-7-do-you-see-the-perl-is-on-the-path-of-recovery&#34;&gt;What do you think about Perl 7? Do you see the Perl is on the path of recovery?&lt;/h2&gt;

&lt;p&gt;I am 100% on board with the project and yes, it&amp;rsquo;s the path for Perl&amp;rsquo;s recovery. I&amp;rsquo;ve seen widespread support for the change, which was heartening, and with the amount of press, even TIOBE moved Perl from 19 to 14th place, though I suspect it will drop back after the press dies down.&lt;/p&gt;

&lt;p&gt;However, there&amp;rsquo;s a difference between having a goal and having a plan. There&amp;rsquo;s widespread agreement on the goal, but there&amp;rsquo;s less agreement about the plan. That&amp;rsquo;s great so long as people can use this to find the best path. It&amp;rsquo;s less great if it devolves into acrimony. Fortunately, Sawyer&amp;rsquo;s been great at projecting a positive message.&lt;/p&gt;

&lt;p&gt;So long as we manage to protect businesses currently using Perl (and that means convincing Linux distros that we&amp;rsquo;re not going to break them), having a plan to better support active and new developers is awesome. And the version number change is a key first step.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-inspired-you-to-start-the-project-cor-when-are-you-planning-to-release-it&#34;&gt;What inspired you to start the project &amp;ldquo;Cor&amp;rdquo;? When are you planning to release it?&lt;/h2&gt;

&lt;p&gt;First, for those who are not familiar with Cor, you can read about it at &lt;a href=&#34;https://github.com/Ovid/Cor/wiki&#34;&gt;https://github.com/Ovid/Cor/wiki&lt;/a&gt;. In short, Cor is a plan to add modern OO to the Perl core. But the motto is &amp;ldquo;&amp;lsquo;Good enough&amp;rsquo; is not good enough.&amp;rdquo; We have to stop settling for what we can have and start dreaming about what we want. For a trivial example, here&amp;rsquo;s a naïve LRU cache implementation in Cor:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;class Cache::LRU {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Hash::Ordered;

    has $max_size :&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;(optional) :reader :isa(PositiveInt) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;;
    has $created  :reader &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time;
    has $cache    :handles(get)  :builder;
    method _build_cache () { Hash::Ordered&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; }

    method set ( $key, $value ) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ( $cache&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;exists($key) ) {
            $cache&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;delete($key);
        }
        &lt;span style=&#34;color:#66d9ef&#34;&gt;elsif&lt;/span&gt; ( $cache&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;keys &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; $max_size ) {
            $cache&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;shift;
        }
        $cache&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;set( $key, $value );  &lt;span style=&#34;color:#75715e&#34;&gt;# new values in front&lt;/span&gt;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As for my motivation, like many developers, I was waiting for Stevan Little to finish his work to get a better OO system for the Perl core. But he was working mostly alone, for a long time, and that&amp;rsquo;s hard to do. So when I decided I wanted something, I was able to take a look at his work and realize it was solid. But I needed a better syntax.&lt;/p&gt;

&lt;p&gt;I tried to refine some of the syntax from Moo/se, but honestly, Moo/se has some serious limitations. Some are design decisions which can be easily corrected, but some are due to limitations in the Perl language itself. Once I had Sawyer&amp;rsquo;s backing, I realized that I didn&amp;rsquo;t just have to steal syntax, I could invent syntax, though I have done so very cautiously. It&amp;rsquo;s important that Cor still be Perl, but just a tiny sprinkling of syntactic sugar in the right spots makes a world of difference. So far it looks promising.&lt;/p&gt;

&lt;p&gt;And Sawyer said he hopes a v1 will be available under a feature guard in 7.2 or 7.4. With Perl 8, the feature guard would be removed.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;how-does-your-company-all-around-the-world-help-people-with-perl&#34;&gt;How does your company &amp;ldquo;All around the world&amp;rdquo; help people with Perl?&lt;/h2&gt;

&lt;p&gt;The consulting world is a mess. Anyone can call themselves a consultant and presto, they&amp;rsquo;re a consultant. This means that for the vast majority of consulting firms out there, quality is very hit-or-miss. So most companies hiring consultants are taking a huge gamble. But banks, insurance companies, and other &amp;ldquo;enterprise&amp;rdquo; companies prefer to stick with high-end consulting firms. From what I&amp;rsquo;ve seen, their code is more likely to do what you want it to do, but that&amp;rsquo;s only if you can afford them.&lt;/p&gt;

&lt;p&gt;So we decided to try a different approach. We can give our customers the reliability they want but at a more reasonable price if we do two things. First, we only hire the handful of senior developers who can pass both our technical test and a structured interview. Second, we limit the number of projects we take so we can dedicate serious attention to each customer. I&amp;rsquo;ll put our team&amp;rsquo;s quality up against the top-tier consulting firms any day of the week. But we&amp;rsquo;re going to cost a much less than they do and we&amp;rsquo;ll deliver faster, too.&lt;/p&gt;

&lt;p&gt;To give a concrete example, we had a client who had two weeks to improve their performance by an order of magnitude. They had worked with us before, so they turned to us. Here&amp;rsquo;s the &lt;a href=&#34;https://ovid.github.io/articles/project-500.html&#34;&gt;case study&lt;/a&gt; of that project. It&amp;rsquo;s a fun read and gives you a lot of insight into how top-level developers really work.&lt;/p&gt;

&lt;p&gt;I should also note that while we have a deep specialization in Perl, we have also done work in quite a few other languages and technologies, such as Golang, C++, Lua, Node, Angular, and so on.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;how-is-tau-station-going-and-how-much-perl-helped-in-building-the-game&#34;&gt;How is &amp;ldquo;Tau Station&amp;rdquo; going and how much Perl helped in building the game?&lt;/h2&gt;

&lt;p&gt;For those not familiar with it, &lt;a href=&#34;https://taustation.space&#34;&gt;Tau Station&lt;/a&gt; is a free to play narrative MMORPG with the backend written entirely in Perl. It&amp;rsquo;s a beautiful sci-fi universe (unlike anything you&amp;rsquo;ve ever played before) and has all the stars within 20 light years of Earth. We&amp;rsquo;re around half a million lines of code and we&amp;rsquo;re still in open alpha. We&amp;rsquo;re currently in the &amp;ldquo;final stretch&amp;rdquo; of building what we feel we need, so we anticipate the launch by the end of this year. Perl&amp;rsquo;s tremendous flexibility has made it very easy to build out many of the features that we&amp;rsquo;ve needed. For example, we have a declarative system for building out many of the behaviors. Here&amp;rsquo;s how you refuel a spaceship:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;        Steps(
            Area(      $character &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; is_in            &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;docks&amp;#39;&lt;/span&gt; ),
            Ship(      $ship      &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; is_owned_by      &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $character ),
            Ship(      $ship      &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; is_docked_on     &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $character&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;station ),
            Character( $character &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; not_onboard_ship &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $ship ),
            Ship(      $ship      &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;needs_refueling&amp;#39;&lt;/span&gt; ),
            Money(     $character &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; pay              &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $ship&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;get_refuel_price ),
            Ship(      $ship      &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;refuel&amp;#39;&lt;/span&gt; ),
            Character(
                $character &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; set_cooldown &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; {
                    cooldown_type  &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;ship_refuel&amp;#39;&lt;/span&gt;,
                    period         &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $ship&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;get_refuel_time,
                },
            ),
        )&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;People are sometimes surprised to learn that this is Perl code because it&amp;rsquo;s so easy to read, but they&amp;rsquo;d be even more surprised to learn that much of this would be harder to write in early-binding languages such as Java.&lt;/p&gt;

&lt;p&gt;And by creating standard components like that, the developer who creates a new kind of behavior for the game often doesn&amp;rsquo;t need to worry about database transactions, exceptions, or messages to the character. Instead, they can quickly assemble these &amp;ldquo;steps&amp;rdquo; in the correct order and you have new gameplay. If we ever had the time, we&amp;rsquo;d love to release the above framework as open source, but that would take time and we need to keep our clients happy, first.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;which-perl-modules-are-you-constantly-using-how-do-they-make-your-life-easier&#34;&gt;Which Perl modules are you constantly using? How do they make your life easier?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&#34;{&amp;lt;% mcpan Test::Class::Moose %&amp;gt;}&#34;&gt;Test::Class::Moose&lt;/a&gt; is a go to module for me. Most Perl developers learn how to test modules, not applications. With &lt;a href=&#34;{&amp;lt;% mcpan Test::Class::Moose %&amp;gt;}&#34;&gt;Test::Class::Moose&lt;/a&gt;, large test suites become easier to build and manage and, when it&amp;rsquo;s written correctly, many test suites can be an order of magnitude faster.&lt;/p&gt;

&lt;p&gt;I also have a module I write for personal code called &lt;code&gt;Less::Boilerplate&lt;/code&gt;. It&amp;rsquo;s not on the CPAN because it&amp;rsquo;s too fine-tuned for my personal needs, but naturally it enables &lt;a href=&#34;{&amp;lt;% mcpan strict %&amp;gt;}&#34;&gt;strict&lt;/a&gt;, &lt;a href=&#34;{&amp;lt;% mcpan warnings %&amp;gt;}&#34;&gt;warnings&lt;/a&gt;, signatures, &lt;a href=&#34;{&amp;lt;% mcpan autodie %&amp;gt;}&#34;&gt;autodie&lt;/a&gt;, and other features without having to type everything out by hand. And it pleases me to have the double meaning of &lt;code&gt;use Less::Boilerplate&lt;/code&gt; at the top of my code. Yet it&amp;rsquo;s part of the issue that Sawyer&amp;rsquo;s pointed out with Perl. New Perl developers don&amp;rsquo;t know the strange incantations experienced Perl developers put at the top of their code to get Perl to be reasonable. That hurts the language because they get a poor &amp;ldquo;out of the box&amp;rdquo; experience.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;which-perl-feature-do-you-overuse&#34;&gt;Which Perl feature do you overuse?&lt;/h2&gt;

&lt;p&gt;It used to be the punctuation variables that I would sprinkle around my code like magic pixie dust. Things like local &lt;code&gt;$&amp;quot; = &#39;, &#39;&lt;/code&gt; were natural to me. But I&amp;rsquo;ve stopped doing that because honestly, it&amp;rsquo;s not readable. I do a lot of client work so I take care to ensure that my code is (as much as I can), easy to read and maintain. I&amp;rsquo;ve even rewritten some of my code to &amp;ldquo;dumb it down&amp;rdquo; because I want to ensure that it&amp;rsquo;s maintainable.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;which-perl-feature-do-you-wish-you-could-use-more&#34;&gt;Which Perl feature do you wish you could use more?&lt;/h2&gt;

&lt;p&gt;Given that clients call me in to help build new systems or fix existing ones, I pretty much get to pick and choose what features I want to use, so I&amp;rsquo;m fortunate in that regard. Thus, there&amp;rsquo;s not much I don&amp;rsquo;t get to use if I think it&amp;rsquo;s useful. However, a feature I wish I could use more is a feature that doesn&amp;rsquo;t exist: more standardized introspection tools, similar to a MOP. Mucking about in the symbol table for the things I need, or pulling in external libraries to find out where my code is located in the filesystem is frustrating. I often write code that magically &amp;ldquo;works&amp;rdquo; without having to be loaded (similar to plugins). But without standardized, cross-platform tools for finding the code, loading it dynamically, converting between package and filenames automatically, I find that I&amp;rsquo;m often rewriting this code again, for a different client, based on their operating system, file system layout, and so on.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;what-one-thing-you-d-like-to-change-about-perl&#34;&gt;What one thing you&amp;rsquo;d like to change about Perl?&lt;/h2&gt;

&lt;p&gt;How variables behave. There are a few things in that, but mainly, I wish Perl had invariant sigils like Raku and that arrays and hashes wouldn&amp;rsquo;t flatten unless requested. But I&amp;rsquo;m not going to get that, so let&amp;rsquo;s pretend I didn&amp;rsquo;t ask :)&lt;/p&gt;

&lt;p&gt;(Hmm, working threads might be interesting, too)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s new on CPAN - June 2020</title>
      <link>https://www.perl.com/article/what-s-new-on-cpan-june-2020/</link>
      <pubDate>Wed, 29 Jul 2020 01:10:28 +0000</pubDate>
      
      <guid>https://www.perl.com/article/what-s-new-on-cpan-june-2020/</guid>
      <description>

&lt;p&gt;Welcome to &amp;ldquo;What&amp;rsquo;s new on CPAN&amp;rdquo;, a curated look at last month&amp;rsquo;s new CPAN uploads for your reading and programming pleasure. Enjoy!&lt;/p&gt;

&lt;h2 id=&#34;apis-apps&#34;&gt;APIs &amp;amp; Apps&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/App::Timestamper::WithElapsed&#34;&gt;App::Timestamper::WithElapsed&lt;/a&gt; for every line of STDIN displays a timestamp and the elapsed seconds since the last line&lt;/li&gt;
&lt;li&gt;Get a command line client for cPanel UAPI and API 2 using &lt;a href=&#34;https://metacpan.org/pod/App::cpanel&#34;&gt;App::cpanel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Introspect C/C++ code with CastXML &lt;a href=&#34;https://metacpan.org/pod/Clang::CastXML&#34;&gt;Clang::CastXML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/OpenTelemetry&#34;&gt;OpenTelemetry&lt;/a&gt; supports application process monitoring as defined by opentelemetry.io&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/OpenTracing::Interface&#34;&gt;OpenTracing::Interface&lt;/a&gt; defines an API for opentracing (precursor to opentelemetry)&lt;/li&gt;
&lt;li&gt;Send SMS via VoIP.ms with &lt;a href=&#34;https://metacpan.org/pod/SMS::Send::VoIP::MS&#34;&gt;SMS::Send::VoIP::MS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;config-devops&#34;&gt;Config &amp;amp; Devops&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/App::PP::Autolink&#34;&gt;App::PP::Autolink&lt;/a&gt; can create standalone Perl executables, finding dynamic libs automatically&lt;/li&gt;
&lt;li&gt;Get a simple interface for creating and verifying One Time Passwords as used by authenticator apps with &lt;a href=&#34;https://metacpan.org/pod/Authen::TOTP&#34;&gt;Authen::TOTP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Guacamole&#34;&gt;Guacamole&lt;/a&gt; is a parser toolkit for Standard Perl - also see Sawyer X&amp;rsquo;s recent &lt;a href=&#34;https://www.youtube.com/watch?v=sTEshbh2lYQ&#34;&gt;talk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Neo4j::Client&#34;&gt;Neo4j::Client&lt;/a&gt; helps configure and build the C based neo4j-client library&lt;/li&gt;
&lt;li&gt;Create and verify password hashes for OpenSMTPD using &lt;a href=&#34;https://metacpan.org/pod/OpenSMTPD::Password&#34;&gt;OpenSMTPD::Password&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quickly extract raw values from Excel XLSX spreadsheets with &lt;a href=&#34;https://metacpan.org/pod/Excel::ValueReader::XLSX&#34;&gt;Excel::ValueReader::XLSX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/SkewHeap::PP&#34;&gt;SkewHeap::PP&lt;/a&gt; is a fast and flexible heap structure&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Text::Mrkdwn::Escape&#34;&gt;Text::Mrkdwn::Escape&lt;/a&gt; can escape text for inclusion in the markdown variant used by Slack&lt;/li&gt;
&lt;li&gt;Perform HTTP Encrypted Content Encoding (AES 128-bit Galois/Counter Mode) with &lt;a href=&#34;https://metacpan.org/pod/Crypt::RFC8188&#34;&gt;Crypt::RFC8188&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;development-version-control&#34;&gt;Development &amp;amp; Version Control&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Analyze/Rename/Track Perl source code, includes a vim plugin: &lt;a href=&#34;https://metacpan.org/pod/Code::ART&#34;&gt;Code::ART&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Future::Buffer&#34;&gt;Future::Buffer&lt;/a&gt; implements a Futures-based string buffer&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Mojolicious::Command::Author::generate::cpanfile&#34;&gt;Mojolicious::Command::Author::generate::cpanfile&lt;/a&gt; creates a cpanfile by scanning your source code for dependencies&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Sys::Pipe&#34;&gt;Sys::Pipe&lt;/a&gt; provides access to the non-blocking &lt;code&gt;pipe2()&lt;/code&gt; system call&lt;/li&gt;
&lt;li&gt;Get fast and minimal code coverage stats using &lt;a href=&#34;https://metacpan.org/pod/Test2::Plugin::Cover&#34;&gt;Test2::Plugin::Cover&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get a chip driver for Noritake GU-D display modules using &lt;a href=&#34;https://metacpan.org/pod/Device::Chip::NoritakeGU_D&#34;&gt;Device::Chip::NoritakeGU_D&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/PINE64::MCP300x&#34;&gt;PINE64::MCP300x&lt;/a&gt; provides an interface to the MCP300x family of 10-bit analog to digital converters&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/PINE64::MCP3208&#34;&gt;PINE64::MCP3208&lt;/a&gt; provides an interface to the MCP3208 12-bit SPI analog to digital converters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;language-international&#34;&gt;Language &amp;amp; International&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Getopt::EX::i18n&#34;&gt;Getopt::EX::i18n&lt;/a&gt; sets the environment locale via a command line option&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Translate::Fluent&#34;&gt;Translate::Fluent&lt;/a&gt; is a Perl implementation of the Mozilla localization project to create more natural-sounding translations&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A tour with Net::FTP</title>
      <link>https://www.perl.com/article/a-tour-with-net-ftp/</link>
      <pubDate>Mon, 13 Jul 2020 11:48:52 +0000</pubDate>
      
      <guid>https://www.perl.com/article/a-tour-with-net-ftp/</guid>
      <description>

&lt;p&gt;When we want to have a way to exchange files between machines, we often think about rsync, scp, git or even something slow and complex (looking at you Artifactory and S3), but the answer is often right in front of your eyes: FTP!&lt;/p&gt;

&lt;p&gt;The &amp;ldquo;File Transfer Protocol&amp;rdquo; provides a very simple and convenient way to share files. It&amp;rsquo;s battle-tested, requires almost no maintenance, and has a simple anonymous access mechanism. It can be integrated with several standard auth methods and even some virtual ones, none of which I show here.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.perl.com/images/a-tour-with-net-ftp/battlereadymeow.jpeg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;p&gt;In this article, I&amp;rsquo;ll install a local FTP server and create a simple FTP client in Perl.&lt;/p&gt;

&lt;h2 id=&#34;a-bit-of-context&#34;&gt;A bit of context&lt;/h2&gt;

&lt;p&gt;At &lt;code&gt;$work&lt;/code&gt; I have to carry on an army of developers that create customized build pipelines from handcrafted local configuration files.&lt;/p&gt;

&lt;p&gt;This file is not hosted &amp;ldquo;by design&amp;rdquo; like you would have with Travis CI or a GitHub Action, but it is used to feed a &amp;ldquo;heavy client&amp;rdquo; that parses, resolves templates, and creates a workspace in some centralized automations servers through HTTP API calls.&lt;/p&gt;

&lt;p&gt;It was a lot of support to help developers to create this file according to the spec (yet another file format), and we were blind when we wanted to help them with failing workspace creation/build (no way to retrieve configuration from workspace).&lt;/p&gt;

&lt;p&gt;I got the idea to backup and centralize automatically the configuration file during the creation of the build pipeline workspace. It was intended to help both developers (configuration &amp;ldquo;samples&amp;rdquo;) and support team (see history, versioned then we can check diffs, file to replay). The constraints were to be able to exchange file from various places with variable users. The FTP protocol is a perfect fit for that.&lt;/p&gt;

&lt;p&gt;I added also a cronjob to autocommit and push to a git repository and we had magically a website listing versioned configurations files.&lt;/p&gt;

&lt;p&gt;In addition, FTP proved later to also require zero support. I mean really zero maintenance!&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.perl.com/images/a-tour-with-net-ftp/toolowmaintenance.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;download-and-install-ftpd&#34;&gt;Download and install ftpd&lt;/h2&gt;

&lt;p&gt;I decided to use &lt;a href=&#34;https://www.pureftpd.org/project/pure-ftpd/&#34;&gt;pure-ftpd&lt;/a&gt; but there are some other good alternatives if you want.&lt;/p&gt;

&lt;p&gt;First I download the tarball, untar it, and change into its directory:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ wget https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.49.tar.gz
$ tar xvzf pure-ftpd-1.0.49.tar.gz
$ cd pure-ftpd-1.0.49/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I configure &lt;code&gt;ftpd&lt;/code&gt; so I can execute it as casual (non-root) user using a non-restricted port, and I&amp;rsquo;ll set the destination directory to my &lt;code&gt;$HOME/ftpd&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ./configure --prefix&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$HOME/ftpd --with-nonroot &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; make install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I create two directories. The &lt;em&gt;ftp&lt;/em&gt; is what I&amp;rsquo;ll publish and &lt;em&gt;run&lt;/em&gt; is where I&amp;rsquo;ll put the pidfile.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ cd $HOME/ftpd
$ mkdir ftp
$ mkdir run&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can start the ftp server. I need to give some custom configurations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FTP_ANON_DIR&lt;/code&gt; is the directory I want to publish&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; allows anonymous access&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-M&lt;/code&gt; allows anonymous users to create directories&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;-g&lt;/code&gt; specifies the directory for the pidfile:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ FTP_ANON_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;pwd&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;/ftp ; ./sbin/pure-ftpd -e -M -g run &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point I should have a running ftp server. Let&amp;rsquo;s check!&lt;/p&gt;

&lt;h2 id=&#34;test-with-ftp&#34;&gt;Test with ftp&lt;/h2&gt;

&lt;p&gt;First, I test with the preinstalled &lt;code&gt;ftp&lt;/code&gt; client. If everything is fine I see the typical FTP exchange:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ftp localhost &lt;span style=&#34;color:#ae81ff&#34;&gt;2121&lt;/span&gt;
Connected to localhost.
&lt;span style=&#34;color:#ae81ff&#34;&gt;220&lt;/span&gt;---------- Welcome to Pure-FTPd ----------
&lt;span style=&#34;color:#ae81ff&#34;&gt;220&lt;/span&gt;-You are user number &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; of &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt; allowed.
&lt;span style=&#34;color:#ae81ff&#34;&gt;220&lt;/span&gt;-Local time is now &lt;span style=&#34;color:#ae81ff&#34;&gt;11&lt;/span&gt;:56. Server port: &lt;span style=&#34;color:#ae81ff&#34;&gt;2121&lt;/span&gt;.
&lt;span style=&#34;color:#ae81ff&#34;&gt;220&lt;/span&gt;-Only anonymous FTP is allowed here
&lt;span style=&#34;color:#ae81ff&#34;&gt;220&lt;/span&gt; You will be disconnected after &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt; minutes of inactivity.
Name &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;localhost:tib&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;:
&lt;span style=&#34;color:#ae81ff&#34;&gt;230&lt;/span&gt; Anonymous user logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If I get &lt;code&gt;ftp: connect: Connection refused&lt;/code&gt; it&amp;rsquo;s probably one of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ftpd&lt;/code&gt; is not running (check with &lt;code&gt;ps aux | grep &amp;quot;ftp[d]&amp;quot;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m using the wrong port&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I get &lt;code&gt;421 Can&#39;t change directory to /home/tib/ftpd/ftp/ [/]&lt;/code&gt; it&amp;rsquo;s probably because I haven&amp;rsquo;t created the directory I specified in &lt;code&gt;FTP_ANON_DIR&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;simple-client-in-perl&#34;&gt;Simple client in Perl&lt;/h2&gt;

&lt;p&gt;Ok that&amp;rsquo;s cool, but I only played with ftp server and preinstalled &lt;code&gt;ftp&lt;/code&gt; client until now. What about writing some Perl now?&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://www.perl.com/images/a-tour-with-net-ftp/whatif.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;h{{&amp;lt; mcpan &amp;quot;Net::FTP&amp;quot; &amp;gt;}}&#34;&gt;Net::FTP&lt;/a&gt; is a superb &lt;a href=&#34;https://metacpan.org/&#34;&gt;CPAN&lt;/a&gt; module dedicated to FTP protocol and I&amp;rsquo;ll use that.&lt;/p&gt;

&lt;h3 id=&#34;simple-listing&#34;&gt;Simple listing&lt;/h3&gt;

&lt;p&gt;First, a very simple listing script &lt;code&gt;ls.pl&lt;/code&gt;. This program connects to the server, asks for a list of files, and outputs each one. It&amp;rsquo;s clear that&amp;rsquo;s super easy and straightforward to play with FTP in Perl!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; strict;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Net::FTP;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $HOST &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $PORT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2121&lt;/span&gt;;


&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Net::FTP&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;($HOST, Port &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $PORT, Debug &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
	&lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot connect to $HOST: $@&amp;#34;&lt;/span&gt;;
$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;login() &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot login &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
&lt;span style=&#34;color:#66d9ef&#34;&gt;foreach&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $f ($ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;ls()) { &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$f\n&amp;#34;&lt;/span&gt;; }
$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;quit;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;upload&#34;&gt;Upload&lt;/h3&gt;

&lt;p&gt;What next?  Maybe upload something? Again, it&amp;rsquo;s super simple. Instead of listing files, I&amp;rsquo;m &lt;code&gt;put&lt;/code&gt;ting them:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; strict;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Net::FTP;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $HOST &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $PORT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2121&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Net::FTP&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;($HOST, Port &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $PORT, Debug &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
	&lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot connect to $HOST: $@&amp;#34;&lt;/span&gt;;
$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;login() &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot login &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
&lt;span style=&#34;color:#66d9ef&#34;&gt;foreach&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $file(@ARGV) {
    $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;put(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$file&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$file&amp;#34;&lt;/span&gt;)
    	&lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot put $file&amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
}
$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;quit;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I run this and supply the files I want to upload:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ perl upload.pl file1.txt file2.txt&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;put-things-together&#34;&gt;Put things together&lt;/h2&gt;

&lt;p&gt;I propose a more complete client with some command-line parsing and more actions. In addition to the previous code for listing and uploading, here I added a way to view a file. &lt;a href=&#34;https://metacpan.org/pod/Getopt::Long&#34;&gt;Getopt::Long&lt;/a&gt; to handle command line parameters.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; strict;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Getopt::Long;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; File::Slurp;

&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; Net::FTP;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $HOST &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $PORT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2121&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; %options &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ();

GetOptions(
	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;action|c=s&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;\&lt;/span&gt;$options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;},
	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file|f=s&amp;#34;&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;\&lt;/span&gt;$options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;},
	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;help|h&amp;#34;&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;\&lt;/span&gt;$options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;help&amp;#39;&lt;/span&gt;}
	);

&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;print_usage&lt;/span&gt;() {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;List all files :\n\t$0 -c list\n&amp;#34;&lt;/span&gt;;
	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Upload file :\n\t$0 -c upload -f file.txt\n&amp;#34;&lt;/span&gt;;
	&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Print file :\n\t$0 -c view -f file.txt\n\n&amp;#34;&lt;/span&gt;;
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_ftp&lt;/span&gt;() {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Net::FTP&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;($HOST, Port &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; $PORT, Debug &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
		&lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot connect to $HOST: $@&amp;#34;&lt;/span&gt;;
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;login() &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot login &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
}

&lt;span style=&#34;color:#75715e&#34;&gt;# ls / on remote ftp&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;list&lt;/span&gt;() {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_ftp();
	&lt;span style=&#34;color:#66d9ef&#34;&gt;foreach&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $f ($ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;ls()) { &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$f\n&amp;#34;&lt;/span&gt;; }
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;quit;
}

&lt;span style=&#34;color:#75715e&#34;&gt;# Upload a file&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;upload&lt;/span&gt;($) {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; shift;
	(&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;e $file) &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;

	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_ftp();
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;login() &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot login &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;put(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$file&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot put $file &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;quit;
}

&lt;span style=&#34;color:#75715e&#34;&gt;# Read a file&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;view&lt;/span&gt;($) {
	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; shift;

	&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ftp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_ftp();
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$file&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; die &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot read $file &amp;#34;&lt;/span&gt;, $ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;message;
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;e $file) { &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt; read_file($file); }
	$ftp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;quit;
}

&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;($options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;} &lt;span style=&#34;color:#f92672&#34;&gt;eq&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;list&amp;#39;&lt;/span&gt;) {
	list();
} &lt;span style=&#34;color:#66d9ef&#34;&gt;elsif&lt;/span&gt;($options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;} &lt;span style=&#34;color:#f92672&#34;&gt;eq&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;upload&amp;#39;&lt;/span&gt;) {
	upload($options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;});
} &lt;span style=&#34;color:#66d9ef&#34;&gt;elsif&lt;/span&gt;($options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;} &lt;span style=&#34;color:#f92672&#34;&gt;eq&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;view&amp;#39;&lt;/span&gt;) {
	view($options{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;});
} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
	print_usage();
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;more-about-design-and-security&#34;&gt;More about design and security&lt;/h2&gt;

&lt;p&gt;This thin wrapper can be extended to do more tasks, such as checking allowed or disallowed name patterns or tidying files depending the uploader or the prefix in the name of the file. Remember, this is only on the client side! If you want real guarantees you would better have to implement some kind of protections on the server side too. But, the goal was not to discuss security here but to play with FTP! And I hope you had a pleasant tour with me and &lt;a href=&#34;https://metacpan.org/pod/Net::FTP&#34;&gt;Net::FTP&lt;/a&gt;!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Listen to Larry Wall&#39;s State of the Onion 2000 on YouTube</title>
      <link>https://www.perl.com/article/listen-to-larry-wall-s-state-of-the-onion-2000-on-youtube/</link>
      <pubDate>Fri, 10 Jul 2020 09:07:55 +0000</pubDate>
      
      <guid>https://www.perl.com/article/listen-to-larry-wall-s-state-of-the-onion-2000-on-youtube/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://metacpan.org/author/TODDR&#34;&gt;Todd Rinaldo&lt;/a&gt; has uploaded Larry&amp;rsquo;s State of the Onion talk from YAPC &lt;del&gt;19100&lt;/del&gt; 2000 to &lt;a href=&#34;https://www.youtube.com/watch?v=a1SEt_-QMDo&#34;&gt;YouTube&lt;/a&gt;. Previously it was available in separate mp3 files, but this is much more accessible.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s a typical Larry talk filled with quirky, humorous observations about life and programming, and notably he announces the Perl 6 project.&lt;/p&gt;

&lt;p&gt;Unfortunately the audio is low quality (hey it was 20 years ago at a low-budget conference); you can read a transcript of the talk &lt;a href=&#34;https://www.perl.com/pub/2000/10/23/soto2000.html/&#34;&gt;here&lt;/a&gt; (with mp3 download links at the bottom). We also have collection of attendees&amp;rsquo; &lt;a href=&#34;https://www.perl.com/pub/2000/07/yapc19101.html/&#34;&gt;reports&lt;/a&gt; from the conference.&lt;/p&gt;

&lt;p&gt;If you enjoy Larry&amp;rsquo;s talks, you might like some of his other &lt;a href=&#34;https://www.perl.com/authors/larry-wall/&#34;&gt;transcribed talks / articles&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Announcing Perl 7</title>
      <link>https://www.perl.com/article/announcing-perl-7/</link>
      <pubDate>Wed, 24 Jun 2020 11:34:35 +0000</pubDate>
      
      <guid>https://www.perl.com/article/announcing-perl-7/</guid>
      <description>

&lt;p&gt;&lt;em&gt;image credit: &lt;a href=&#34;https://www.flickr.com/photos/darren/&#34;&gt;Darren Wood&lt;/a&gt;, &lt;a href=&#34;https://www.flickr.com/photos/darren/3680674672/in/photolist-6Bfqm9-ino1FQ-g9QYp-LBqJ8U-2imZyN9-2g4LBC9-JrtM4R-MsDZU1-MkbMoz-BSxoYD-KHTzJX-JYzksq-G9dfcP-G5Byr3-LrnQMb-6hwfHT-9i4upm-oJfAkJ-8cQQBf-6NVCN1-Ph8487-N1UVUo-mrXQmx-8GoTKf-6fqvZk-Gi1cPH-Mae7Mo-282AxcA-Hvehqx-HbZrvj-YoKVff-H1FRCw-d81uq-jyUXx9-JZGmJj-JTpLp-82ZDob-P19B5f-EQFLnh-aJpXi-LyYS7u-9X3iK-CCTZD-bdCtm-5SGWuB-ET4D6C-9vWh2c-4mieMj-HpYqSw-2iHee4g&#34;&gt;&amp;ldquo;7&amp;rdquo;&lt;/a&gt;, on Flickr.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;This morning at &lt;a href=&#34;https://perlconference.us/tpc-2020-cloud/&#34;&gt;The Perl Conference in the Cloud&lt;/a&gt;, Sawyer X announced that Perl has a new plan moving forward. Work on Perl 7 is already underway, but it&amp;rsquo;s not going to be a huge change in code or syntax. It&amp;rsquo;s Perl 5 with modern defaults and it sets the stage for bigger changes later. My latest book &lt;a href=&#34;https://leanpub.com/preparing_for_perl7&#34;&gt;Preparing for Perl 7&lt;/a&gt; goes into much more detail.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;perl-7-is-going-to-be-perl-5-32-mostly&#34;&gt;Perl 7 is going to be Perl 5.32, mostly&lt;/h2&gt;

&lt;p&gt;Perl 7.0 is going to be v5.32 but with different, saner, more modern defaults. You won&amp;rsquo;t have to enable most of the things you are already doing because they are enabled for you. The major version jump sets the boundary between how we have been doing things and what we can do in the future.&lt;/p&gt;

&lt;p&gt;Remember, Perl was the &amp;ldquo;Do what I mean&amp;rdquo; language where the defaults were probably what you wanted to do. In Perl 4 and the early days of Perl 5, that was easy. But, it&amp;rsquo;s been a couple of decades and the world is more complicated now. We kept adding pragmas, but with Perl&amp;rsquo;s commitment to backward compatibility, we can&amp;rsquo;t change the default settings. Now we&amp;rsquo;re back to the old days of C where we have to include lots of boilerplate before we start doing something:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; utf8;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; strict;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; open &lt;span style=&#34;color:#e6db74&#34;&gt;qw(:std :utf8)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; feature &lt;span style=&#34;color:#e6db74&#34;&gt;qw(indirect)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; feature &lt;span style=&#34;color:#e6db74&#34;&gt;qw(signatures)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; warnings &lt;span style=&#34;color:#e6db74&#34;&gt;qw(experimental::signatures)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is slightly better with v5.12 and later because we get &lt;a href=&#34;https://www.effectiveperlprogramming.com/2010/08/implicitly-turn-on-strictures-with-perl-5-12/&#34;&gt;&lt;code&gt;strict&lt;/code&gt; for free&lt;/a&gt; by using setting a minimum version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; v5&lt;span style=&#34;color:#ae81ff&#34;&gt;.32&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; utf8;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; warnings;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; open &lt;span style=&#34;color:#e6db74&#34;&gt;qw(:std :utf8)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; feature &lt;span style=&#34;color:#e6db74&#34;&gt;qw(indirect)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; feature &lt;span style=&#34;color:#e6db74&#34;&gt;qw(signatures)&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; warnings &lt;span style=&#34;color:#e6db74&#34;&gt;qw(experimental::signatures)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Perl 7 is a chance to make some of these the default even without specifying the version. Perl 5 still has Perl 5&amp;rsquo;s extreme backward compatibility behavior, but Perl 7 gets modern practice with minimal historical baggage. I&amp;rsquo;m personally hoping signatures makes the cut, but there&amp;rsquo;s still much to be done to make Unicode the default, so you&amp;rsquo;ll probably need to keep some of that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; utf8;
&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; open &lt;span style=&#34;color:#e6db74&#34;&gt;qw(:std :utf8)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You might miss some seedier features that you shouldn&amp;rsquo;t be using anyway, such as the indirect object notation. Larry Wall said he had to do something for the C++ programmers:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $cgi &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; CGI;  &lt;span style=&#34;color:#75715e&#34;&gt;# indirect object, but not in Perl 7&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $cgi &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; CGI&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;# direct object&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But, the feature doesn&amp;rsquo;t really disappear in Perl 7. It&amp;rsquo;s already &lt;a href=&#34;https://www.effectiveperlprogramming.com/2020/06/turn-off-indirect-object-notation/&#34;&gt;a setting in v5.32&lt;/a&gt;, but now with a different default.&lt;/p&gt;

&lt;h2 id=&#34;what-s-happening-to-perl-5&#34;&gt;What&amp;rsquo;s happening to Perl 5?&lt;/h2&gt;

&lt;p&gt;No one is taking Perl 5 away from you; it goes into long term maintenance mode—a lot longer than the two years of rolling support for the two latest user versions. That might be up to a decade from now (or half the time Perl 5 has already been around).&lt;/p&gt;

&lt;h2 id=&#34;when-is-this-happening&#34;&gt;When is this happening?&lt;/h2&gt;

&lt;p&gt;The work is happening now, but you won&amp;rsquo;t need to worry about it for about six months when the first release candidate should appear. The target for a user release of Perl 7.0 within the next year, with some release candidates along the way.&lt;/p&gt;

&lt;p&gt;This is an easy promise to keep, too, since Perl 7 is mostly v5.32 with different defaults. There&amp;rsquo;s no big rewrite or new features, although some currently experimental features may stabilize (please choose signatures!).&lt;/p&gt;

&lt;h2 id=&#34;what-about-cpan&#34;&gt;What about CPAN?&lt;/h2&gt;

&lt;p&gt;The Comprehensive Perl Archive Network, CPAN, has almost 200,000 modules. The maintained modules that people are using should still work, and for the rest there will be a compatibility mode. Remember  Perl 7 is mostly v5.32 so you shouldn&amp;rsquo;t need to change much.&lt;/p&gt;

&lt;p&gt;You may not know that the &lt;a href=&#34;https://lists.perl.org/list/perl5-porters.html&#34;&gt;Perl5 Porters&lt;/a&gt; tests new versions against almost all of CPAN. There&amp;rsquo;s a long history of tools to check the effect that changes may have on the Perl community. As a module author, I often get messages from various people, mostly Andreas Koenig or Slaven Rezić, about weird things in my modules that may break with new Perls. Usually, it&amp;rsquo;s something I need to update anyway. Tracking down problems with existing code is a solved problem. Fixing code shouldn&amp;rsquo;t be that onerous because it&amp;rsquo;s still Perl 5, but with better practices.&lt;/p&gt;

&lt;p&gt;Will there be a separate CPAN for Perl 7? No one has said there can&amp;rsquo;t be, but in the jump to Perl 7, the developers don&amp;rsquo;t want to redo what&amp;rsquo;s already working. This change should be manageable with as few side quests as possible.&lt;/p&gt;

&lt;p&gt;Also, PAUSE, the Perl Authors Upload Server, has received quite a bit of love in the past couple of years. That makes it easier for them to adapt to future needs. The people working on that are experienced and talented, and they&amp;rsquo;ve made the codebase much more tractable.&lt;/p&gt;

&lt;h2 id=&#34;why-the-jump-to-a-major-version&#34;&gt;Why the jump to a major version?&lt;/h2&gt;

&lt;p&gt;A major version can have a different contract with the user. A major version jump changes that contract with new default behavior, even if that conflicts with the past. There will be a way to reset all of those settings to the old Perl 5 default if you like. Perl 7 code will still be v5.32 code (mostly) in syntax and behavior though.&lt;/p&gt;

&lt;p&gt;Sawyer speaks about three major market segments of Perl users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People who are never going to change their code&lt;/li&gt;
&lt;li&gt;People who use new features&lt;/li&gt;
&lt;li&gt;People starting from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perl 5&amp;rsquo;s social contract is extreme backward compatibility, and has been amazingly successful with that. The problem is that the extreme backward compatibility works for those who won&amp;rsquo;t update their code, but doesn&amp;rsquo;t help the two other segments. The new features crowd has to deal with a longer boilerplate section in every program, and newbies wonder why they have to include so much just to create a program so people on StackOverflow won&amp;rsquo;t hector them over missing pragmas.&lt;/p&gt;

&lt;h2 id=&#34;why-7-and-not-6&#34;&gt;Why 7 and not 6?&lt;/h2&gt;

&lt;p&gt;There are two parts to this answer. First, &amp;ldquo;Perl 6&amp;rdquo; was already taken by what is now known as &lt;a href=&#34;https://raku.org&#34;&gt;Raku&lt;/a&gt;. A long time ago, we thought that a very ambitious rewrite effort would replace v5.8. In short, that&amp;rsquo;s not what happened and the language has gone on to live a life of its own.&lt;/p&gt;

&lt;p&gt;So, 7 was the next available number. That&amp;rsquo;s it. It&amp;rsquo;s just the next cardinal number in line. It&amp;rsquo;s not unheard of to make such a jump: PHP went directly from 5 to 7, and isn&amp;rsquo;t it time to steal something from that community? Consider these other weird jumps in history:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solaris 2.6 to Solaris 7&lt;/li&gt;
&lt;li&gt;Java 1.4 to Java 5&lt;/li&gt;
&lt;li&gt;Postgres 9.x as the major version to Postgres 10 as the major version&lt;/li&gt;
&lt;li&gt;Windows 3.1 to Windows 95 (98, ME, 2000, XP, Vista, 7, 8, 10)&lt;/li&gt;
&lt;li&gt;TeX (each new version more closely approximates π)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At least it&amp;rsquo;s not Perl 34.&lt;/p&gt;

&lt;h2 id=&#34;what-s-disappearing&#34;&gt;What&amp;rsquo;s disappearing?&lt;/h2&gt;

&lt;p&gt;Not much. Some things will be disabled by default, but again, this is essentially Perl 5.32 with the knobs and dials in different places. There are some things you should learn to live without, even in Perl 5 land. These are the likely candidates for the first round of changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;indirect object notation&lt;/li&gt;
&lt;li&gt;bareword filehandles (except maybe the standard filehandles)&lt;/li&gt;
&lt;li&gt;fake multidimensional arrays and hashes (old Perl 4 trick)&lt;/li&gt;
&lt;li&gt;Old-style prototype definitions (use &lt;code&gt;:prototype()&lt;/code&gt; instead)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;what-s-appearing&#34;&gt;What&amp;rsquo;s appearing?&lt;/h2&gt;

&lt;p&gt;Not much. Perl 7 is mostly Perl v5.32, but with all of the features enabled by default. You don&amp;rsquo;t have to do anything to get most new features, such as &lt;a href=&#34;https://www.effectiveperlprogramming.com/2014/09/use-postfix-dereferencing/&#34;&gt;postfix dereferencing&lt;/a&gt;, the new &lt;a href=&#34;https://www.effectiveperlprogramming.com/2020/01/use-the-infix-class-instance-operator/&#34;&gt;&lt;code&gt;isa&lt;/code&gt; operator&lt;/a&gt;, or several other features. That&amp;rsquo;s the benefit of the new social contract a major version provides. It&amp;rsquo;s a hard boundary where new features can exist by default on one side without disturbing the other side.&lt;/p&gt;

&lt;h2 id=&#34;what-should-i-do-right-now&#34;&gt;What should I do right now?&lt;/h2&gt;

&lt;p&gt;If you need an older Perl to run your code, you are going to be fine. Those old versions are not going to disappear. Just like Perl 5.6 is still available, if that&amp;rsquo;s the version you wish to run.&lt;/p&gt;

&lt;p&gt;If your code runs without a problem under strictures and warnings, and you are using modern Perl style, you&amp;rsquo;re probably mostly good. If you have some bareword filehandles, start converting those. Same with the indirect object notation.&lt;/p&gt;

&lt;p&gt;With messy code, you aren&amp;rsquo;t out of luck. There will be compatibility modes to assist you in the transition from Perl 5 to 7 (but not Perl 5 to 8). A pragma will set the knobs and dials back to the old settings (but this is more of a one version thing):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;use&lt;/span&gt; compat::perl5;  &lt;span style=&#34;color:#75715e&#34;&gt;# act like Perl 5&amp;#39;s defaults&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For modules, there are some issues to shake out, but there will be a compatibility mechanism for those too.&lt;/p&gt;

&lt;p&gt;The good news is that these things are already being tested by major Perl stakeholders in production settings. This isn&amp;rsquo;t a paper plan: it&amp;rsquo;s already happening and the rough edges are being sanded out.&lt;/p&gt;

&lt;p&gt;And, v5.32 has one of these knobs and dials in place already. You can &lt;a href=&#34;https://www.effectiveperlprogramming.com/2020/06/turn-off-indirect-object-notation/&#34;&gt;turn off the indirect object notation&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; feature &lt;span style=&#34;color:#e6db74&#34;&gt;qw(indirect)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But expect two more knobs or dials, maybe like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; multidimensional;
&lt;span style=&#34;color:#66d9ef&#34;&gt;no&lt;/span&gt; bareword::filehandle;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&amp;rsquo;m collecting all of this information in &lt;a href=&#34;https://leanpub.com/preparing_for_perl7&#34;&gt;Preparing for Perl 7&lt;/a&gt;, my latest offering through &lt;a href=&#34;https://perlschool.com&#34;&gt;Perl School&lt;/a&gt; and LeanPub.&lt;/p&gt;

&lt;h2 id=&#34;the-bottom-line&#34;&gt;The bottom line&lt;/h2&gt;

&lt;p&gt;Perl 7 is v5.32 with different settings. Your code should work if it&amp;rsquo;s not a mess. Expect a user release within a year.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s new on CPAN - May 2020</title>
      <link>https://www.perl.com/article/what-s-new-on-cpan-may-2020/</link>
      <pubDate>Sat, 20 Jun 2020 13:40:05 +0000</pubDate>
      
      <guid>https://www.perl.com/article/what-s-new-on-cpan-may-2020/</guid>
      <description>

&lt;p&gt;Welcome to &amp;ldquo;What&amp;rsquo;s new on CPAN&amp;rdquo;, a curated look at last month&amp;rsquo;s new CPAN uploads for your reading and programming pleasure. Enjoy!&lt;/p&gt;

&lt;h2 id=&#34;apis-apps&#34;&gt;APIs &amp;amp; Apps&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Perl Layout Executor with &lt;a href=&#34;https://metacpan.org/pod/App::plx&#34;&gt;App::plx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/FIDO::Raw&#34;&gt;FIDO::Raw&lt;/a&gt; provides bindings to the libfido2 library&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Geo::LibProj::cs2cs&#34;&gt;Geo::LibProj::cs2cs&lt;/a&gt; is a wrapper for the cs2cs command line client, part of the PROJ coordinate transformation library&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Graph::Nauty&#34;&gt;Graph::Nauty&lt;/a&gt; provides bindings to Nauty (No AUTomorphisms, Yes?)&lt;/li&gt;
&lt;li&gt;Post OCR requests to ocr.space&amp;rsquo;s API with &lt;a href=&#34;https://metacpan.org/pod/OCR::OcrSpace&#34;&gt;OCR::OcrSpace&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;config-devops&#34;&gt;Config &amp;amp; Devops&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create reciples to declare and resolve dependencies between things with &lt;a href=&#34;https://metacpan.org/pod/Beam::Make&#34;&gt;Beam::Make&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Elliptic Curve Cryptography Library with &lt;a href=&#34;https://metacpan.org/pod/Crypto::ECC&#34;&gt;Crypto::ECC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::Redis&#34;&gt;HealthCheck::Diagnostic::Redis&lt;/a&gt; provides a healthcheck for Redis&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::SMTP&#34;&gt;HealthCheck::Diagnostic::SMTP&lt;/a&gt; performs a connectivity healthcheck to an SMTP mail server&lt;/li&gt;
&lt;li&gt;Show diffs of changes to files managed by Rex with &lt;a href=&#34;https://metacpan.org/pod/Rex::Hook::File::Diff&#34;&gt;Rex::Hook::File::Diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mask secrets in log files with &lt;a href=&#34;https://metacpan.org/pod/String::Secret&#34;&gt;String::Secret&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/File::Groups&#34;&gt;File::Groups&lt;/a&gt; returns file extensions and media types for different files&lt;/li&gt;
&lt;li&gt;Get Digi-ID implementation with &lt;a href=&#34;https://metacpan.org/pod/DigiByte::DigiID&#34;&gt;DigiByte::DigiID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Get elevation data for a given lat/lon using &lt;a href=&#34;https://metacpan.org/pod/Geo::Elevation::HGT&#34;&gt;Geo::Elevation::HGT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/JSON::Karabiner&#34;&gt;JSON::Karabiner&lt;/a&gt; can easy JSON code generaation for Karabiner-Elements, the macOS keyboard customizer&lt;/li&gt;
&lt;li&gt;Validate JSON against a schema against the latest draft with &lt;a href=&#34;https://metacpan.org/pod/JSON::Schema::Draft201909&#34;&gt;JSON::Schema::Draft201909&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;development-version-control&#34;&gt;Development &amp;amp; Version Control&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Documentation and tools for using Platypus with Go: &lt;a href=&#34;https://metacpan.org/pod/FFI::Platypus::Lang::Go&#34;&gt;FFI::Platypus::Lang::Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Future::IO::Impl::Glib&#34;&gt;Future::IO::Impl::Glib&lt;/a&gt; implement Future::IO using Glib&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Mu::Tiny&#34;&gt;Mu::Tiny&lt;/a&gt; is an even tinier object system&lt;/li&gt;
&lt;li&gt;Get a Try-Catch block (uses PPI) via &lt;a href=&#34;https://metacpan.org/pod/Nice::Try&#34;&gt;Nice::Try&lt;/a&gt; (great name!)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Number::Textify&#34;&gt;Number::Textify&lt;/a&gt; turns numbers into human-readable strings (customizable)&lt;/li&gt;
&lt;li&gt;Write composable, reusable tests with roles and Moo using &lt;a href=&#34;https://metacpan.org/pod/Test2::Roo&#34;&gt;Test2::Roo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Device::Chip::BNO055&#34;&gt;Device::Chip::BNO055&lt;/a&gt; provides a chip driver for BNO055&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/PINE64::GPIO&#34;&gt;PINE64::GPIO&lt;/a&gt; provides an interface to PineA64 and PineA64+ GPIO pins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;web&#34;&gt;Web&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Catalyst::View::MojoTemplate&#34;&gt;Catalyst::View::MojoTemplate&lt;/a&gt;: use Mojolicious templates in Catalyst views&lt;/li&gt;
&lt;li&gt;Store Dancer2 session data in serealized files using &lt;a href=&#34;https://metacpan.org/pod/Dancer2::Session::Sereal&#34;&gt;Dancer2::Session::Sereal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Find elements in a HTML::Element DOM using CSS selectors with &lt;a href=&#34;https://metacpan.org/pod/HTML::Selector::Element&#34;&gt;HTML::Selector::Element&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Place a limit on &amp;ldquo;concurrent&amp;rdquo; promises with &lt;a href=&#34;https://metacpan.org/pod/Mojo::Promise::Limiter&#34;&gt;Mojo::Promise::Limiter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add role-based access with context to a Mojo app via  &lt;a href=&#34;https://metacpan.org/pod/Mojolicious::Plugin::ContextAuth&#34;&gt;Mojolicious::Plugin::ContextAuth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/POE::Component::SmokeBox::Recent::HTTP&#34;&gt;POE::Component::SmokeBox::Recent::HTTP&lt;/a&gt; is an extremely minimal HTTP client&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The Perl Ambassador: Gabor Szabo</title>
      <link>https://www.perl.com/article/the-perl-ambassador-gabor-szabo/</link>
      <pubDate>Mon, 15 Jun 2020 07:30:00 +0000</pubDate>
      
      <guid>https://www.perl.com/article/the-perl-ambassador-gabor-szabo/</guid>
      <description>

&lt;p&gt;This is the launch interview of a monthly series of interviews I&amp;rsquo;ll
publish on perl.com. I can promise you, fun and entertaining
interviews every month. So please watch this space. If you&amp;rsquo;d like me
to interview you, or know someone you&amp;rsquo;d like me to interview, let me
know. Take the same set of questions and send me your answers!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gabor Szabo&lt;/strong&gt; is a long time Perl developer and DevOps trainer and the
author of the &lt;a href=&#34;https://perlmaven.com/perl-tutorial&#34;&gt;Perl tutorial&lt;/a&gt; and
of Perl Maven and on &lt;a href=&#34;https://code-maven.com/&#34;&gt;Code Maven&lt;/a&gt;. He
received a &lt;a href=&#34;http://whitecamel.org/p/gabor_szabo.html&#34;&gt;White Camel
Award&lt;/a&gt; in 2008. He teaches
&lt;a href=&#34;https://hostlocal.com/&#34;&gt;training courses in Israel&lt;/a&gt; and around the
world. He wears the hat of the chief editor of &lt;a href=&#34;https://perlweekly.com/&#34;&gt;Perl Weekly
newsletter&lt;/a&gt;, and is always happy to receive
notable Perl news items for inclusion in its next issue.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;how-did-you-first-start-using-perl&#34;&gt;How did you first start using Perl?&lt;/h4&gt;

&lt;p&gt;I was working at a start-up company near Jerusalem that had an
AI-based software product which cost 1,000,000 USD with an additional
1-2 million cost for integration. That made sales a bit difficult so
we were working on a related product that would sell for a mere 30,000
USD. Just to get our feet in the door of the potential buyers of our
flagship product. We were using
&lt;a href=&#34;https://en.wikipedia.org/wiki/Scheme_(programming_language)&#34;&gt;Scheme&lt;/a&gt;
and &lt;a href=&#34;https://en.wikipedia.org/wiki/AWK&#34;&gt;AWK&lt;/a&gt; to write our compiler on
Window 3.11. It was great fun, but I was also interested in all the
sysadmin work in the company (we had a Novell NetWare 3.11
&lt;a href=&#34;https://en.wikipedia.org/wiki/NetWare&#34;&gt;network&lt;/a&gt; and all the other
areas that was not that interesting for the regular programmers. For
example our build system.&lt;/p&gt;

&lt;p&gt;Then &lt;a href=&#34;https://en.wikipedia.org/wiki/Windows_NT&#34;&gt;Windows NT&lt;/a&gt; was
introduced in 1993 and I got the opportunity to start setting it up.
At around the same time our office was bought by
&lt;a href=&#34;https://en.wikipedia.org/wiki/NetManage&#34;&gt;NetManage&lt;/a&gt;, one of the
pioneers in TCP/IP for MS Windows, in what is today called an
&lt;a href=&#34;https://en.wikipedia.org/wiki/Acqui-hiring&#34;&gt;Acqui-hiring&lt;/a&gt;. There we
used some &lt;a href=&#34;https://en.wikipedia.org/wiki/Rational_ClearCase&#34;&gt;Rational ClearCase&lt;/a&gt;
tools for bug tracking.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s the time when I first started to use Perl, probably in 1993 or
1994. I built an in-house web application to allow the developers to
initiate a build of the software they were writing and to get
notification when the build was ready. As I recall it was running on
Windows. I also dealt with some of the bug-tracking automation that
was running on some Unix system.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;which-perl-modules-are-you-constantly-using-how-do-they-make-your-life-easier&#34;&gt;Which Perl modules are you constantly using? How do they make your life easier?&lt;/h4&gt;

&lt;p&gt;I hardly have any Perl-related work these days so I can&amp;rsquo;t really say,
but when I need a script here and there I often use &lt;a href=&#34;https://metacpan.org/pod/Capture::Tiny&#34;&gt;Capture::Tiny&lt;/a&gt; and
keep re-creating it (partially and badly) in other languages. I love
testing so anything that starts with &lt;code&gt;Test::&lt;/code&gt; is usually interesting
to me.&lt;/p&gt;

&lt;p&gt;I also run the &lt;a href=&#34;https://perlmaven.com/&#34;&gt;Perl Maven&lt;/a&gt; and
&lt;a href=&#34;https://code-maven.com/&#34;&gt;Code Maven&lt;/a&gt; sites on a Dancer-based
application I wrote ages ago. The source is
&lt;a href=&#34;https://github.com/szabgab/Perl-Maven&#34;&gt;open&lt;/a&gt; though probably not
very useful to anyone besides me. So I use &lt;a href=&#34;https://metacpan.org/pod/Dancer2&#34;&gt;Dancer2&lt;/a&gt;,
&lt;a href=&#34;https://metacpan.org/pod/Template&#34;&gt;Template Toolkit&lt;/a&gt;, &lt;a href=&#34;https://metacpan.org/pod/DateTime&#34;&gt;DateTime&lt;/a&gt;,
and &lt;a href=&#34;https://metacpan.org/pod/DateTime::Tiny&#34;&gt;DateTime::Tiny&lt;/a&gt; just to name a
few. Oh and of course I love &lt;a href=&#34;https://metacpan.org/pod/Perl::Critic&#34;&gt;Perl::Critic&lt;/a&gt; and
&lt;a href=&#34;https://metacpan.org/pod/Devel::Cover&#34;&gt;Devel::Cover&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;which-perl-feature-do-you-overuse&#34;&gt;Which Perl feature do you overuse?&lt;/h4&gt;

&lt;p&gt;I am not sure if any. Well, maybe except of &lt;code&gt;Perl::Critic&lt;/code&gt;. I just
noticed that I configured it that it won&amp;rsquo;t allow double-quotes around
a string if there is nothing to interpolate in it. So &amp;ldquo;perl&amp;rdquo; is bad,
&amp;lsquo;perl&amp;rsquo; is good. I need to relax this.&lt;/p&gt;

&lt;p&gt;I think I hardly ever used the fun features of Perl. I almost never
use the &lt;code&gt;do_this and do_that&lt;/code&gt; construct except for the &lt;code&gt;open or die&lt;/code&gt;.
I hardly use &lt;code&gt;$_&lt;/code&gt; and I think never use it explicitly. Maybe I was never
a real Perl programmer :)&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;which-perl-feature-do-you-wish-you-could-use-more&#34;&gt;Which Perl feature do you wish you could use more?&lt;/h4&gt;

&lt;p&gt;Given that I hardly write Perl these days, any feature would be ok
with me :)&lt;/p&gt;

&lt;p&gt;I write mostly Python, Groovy, and recently Golang. So I would say I
miss the autovivification, though definitely not the bug Perl has in
being overenthusiastic about autovivification. I miss the possibility
to move around some code, or comment out some code and try the rest
without re-indenting everything. Though I don&amp;rsquo;t miss the time when I
was begging my Perl students to indent their code.&lt;/p&gt;

&lt;p&gt;I miss the CPAN Testers. (in these other languages). (And I do still
encounter Perl code in some corporation written by people who have
been writing Perl for 5-10 years and I always wonder why don&amp;rsquo;t they
actually learn Perl&amp;hellip;)&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-one-thing-you-d-like-to-change-about-perl&#34;&gt;What one thing you&amp;rsquo;d like to change about Perl?&lt;/h4&gt;

&lt;p&gt;The community. Whatever that means. I wish people were prouder of
their work and embraced the 21st century.&lt;/p&gt;

&lt;p&gt;I wish they were more public about their work (e.g. announcements of
releases of perl IMHO are only published on the p5porters list.
Not on &lt;a href=&#34;http://blogs.perl.org&#34;&gt;blogs.perl.org&lt;/a&gt;, not on &lt;a href=&#34;https://www.perl.org&#34;&gt;perl.org&lt;/a&gt;, and not on
&lt;a href=&#34;https://news.perlfoundation.org/&#34;&gt;https://news.perlfoundation.org/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Very few module authors write about new releases of their code. There
are very few people who write about Perl-related subjects. In many
cases those posts are not linking to each other.&lt;/p&gt;

&lt;p&gt;Some of the bloggers seem to have forgotten (or never learned) that
links are a form of supporting each other. This is sad as it gives the
impression that no-one uses Perl. Of course this is not new, it is
just getting worse every year as the people who used to write about
Perl stopped doing so or are writing about other subjects now.&lt;/p&gt;

&lt;p&gt;It also makes it much harder to fill
&lt;a href=&#34;https://perlweekly.com/&#34;&gt;Perl Weekly newsletter&lt;/a&gt;. If it wasn&amp;rsquo;t for the
&lt;a href=&#34;https://perlweeklychallenge.org/&#34;&gt;Perl Weekly Challenge&lt;/a&gt; we would
have half the size.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-is-the-future-of-perl&#34;&gt;What is the future of Perl?&lt;/h4&gt;

&lt;p&gt;I think the number of &amp;ldquo;Perl programmers&amp;rdquo; will continue to decline and
with that less and less problems will have a solution on CPAN.&lt;/p&gt;

&lt;p&gt;However, the more interesting thing to me is what happens to the
&amp;ldquo;Perl programmers&amp;rdquo;. The same way the impact of Larry Wall on
programming goes far beyond the people who use (or ever used) Perl.
Or &lt;a href=&#34;https://en.wikipedia.org/wiki/Patch_(Unix)&#34;&gt;patch&lt;/a&gt; for that
matter.&lt;/p&gt;

&lt;p&gt;For example I would love to know what happened to all the people who
received a
&lt;a href=&#34;https://www.perl.org/advocacy/white_camel&#34;&gt;White Camel Award&lt;/a&gt; even
if they don&amp;rsquo;t write Perl any more.&lt;/p&gt;

&lt;p&gt;Same with the most high-profile CPAN authors. Even if they don&amp;rsquo;t write
Perl any more, their thinking was formed by Perl and by all the nice
things the community had throughout the last 32+ years.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Perl Hacks, Perl School, and the future of Perl publishing</title>
      <link>https://www.perl.com/article/perl-hacks-perl-school-and-the-future-of-perl-publishing/</link>
      <pubDate>Thu, 28 May 2020 09:44:03 +0000</pubDate>
      
      <guid>https://www.perl.com/article/perl-hacks-perl-school-and-the-future-of-perl-publishing/</guid>
      <description>

&lt;p&gt;Dave Cross, long-time Perl user, trainer, and author, recently released &lt;a href=&#34;https://perlhacks.com/2020/04/the-best-of-perl-hacks/&#34;&gt;The Best of Perl Hacks&lt;/a&gt;, a curated collection of his best posts from his &lt;a href=&#34;https://perlhacks.com&#34;&gt;Perl Hacks blog&lt;/a&gt;. His imprint, &lt;a href=&#34;https://perlschool.com&#34;&gt;Perl School&lt;/a&gt;, has published six e-books, including two that I wrote.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s an unrelated book, &lt;a href=&#34;http://shop.oreilly.com/product/9780596526740.do&#34;&gt;Perl Hacks: Tips &amp;amp; Tools For Programming, Debugging, And Surviving&lt;/a&gt;, by chromatic, Damian Conway, and Curtis &amp;ldquo;Ovid&amp;rdquo; Poe. It&amp;rsquo;s also very good, but completely separate from Dave&amp;rsquo;s.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-is-perl-hacks-when-did-you-start-it-and-what-do-you-like-to-post-there&#34;&gt;What is Perl Hacks? When did you start it and what do you like to post there?&lt;/h4&gt;

&lt;p&gt;Perl Hacks is my Perl blog. It&amp;rsquo;s where I post all my Perl-related articles.&lt;/p&gt;

&lt;p&gt;I started it in May 2009. Before then, pretty much everyone in the
Perl community used to blog on a site called &lt;a href=&#34;https://use-perl.github.io&#34;&gt;Use
Perl&lt;/a&gt;. But that site was starting to look
a bit dated and a number of people moved their blogs to other places
at around the same time. It&amp;rsquo;s no coincidence that the
&lt;a href=&#34;https://blogs.perl.org&#34;&gt;blogs.perl.org&lt;/a&gt; site also dates from the same
year.&lt;/p&gt;

&lt;p&gt;My rule for choosing what to post on the site is basically &amp;ldquo;is this
about Perl?&amp;rdquo; But looking back over the lifetime of the site (which I
did when compiling the book) I noticed that the type of article had
changed over time. When I first started, there were a lot of &amp;ldquo;newsy&amp;rdquo;
entries—&amp;rdquo;London.pm will be holding these meetings&amp;rdquo;, &amp;ldquo;I&amp;rsquo;m running a
training course&amp;rdquo;, things like that. But later I started posting longer
articles about the Perl community or interesting technical corners of
Perl.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;how-did-you-choose-what-went-into-the-ebook-what-are-some-of-your-favorite-posts-which-ones-got-the-best-responses&#34;&gt;How did you choose what went into the ebook? What are some of your favorite posts? Which ones got the best responses?&lt;/h4&gt;

&lt;p&gt;I basically read through the site over a weekend. I ignored all of the
short articles and anything that was topical and would no longer be
interesting. I then did a second pass, planning to get to about fifty
articles. I think I ended up with fifty-seven.&lt;/p&gt;

&lt;p&gt;There are a couple of technical articles that I&amp;rsquo;m particularly pleased
with. &lt;a href=&#34;https://perlhacks.com/2014/01/dots-perl/&#34;&gt;Dots and Perl&lt;/a&gt;
explains Perl&amp;rsquo;s five operators that are just made of dots. Can you
name them all? Ok, strictly speaking, one of them isn&amp;rsquo;t actually an
operator. And &lt;a href=&#34;https://perlhacks.com/2015/04/subroutines-and-ampersands/&#34;&gt;Subroutines and
Ampersands&lt;/a&gt;
was written so I had somewhere to point people who still insist on
putting ampersands on subroutine calls. It carefully explains why it&amp;rsquo;s
rarely necessary (and hasn&amp;rsquo;t been since Perl 5 was released).&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s also &lt;a href=&#34;https://perlhacks.com/2015/12/long-death-cgi-pm/&#34;&gt;The Long Death of
CGI.pm&lt;/a&gt; which
investigated the effects that removing
&lt;a href=&#34;https://metacpan.org/pod/CGI&#34;&gt;CGI.pm&lt;/a&gt; from the Perl core distribution
would have. I thought there was some nice detective work in there.&lt;/p&gt;

&lt;p&gt;The post that got the most response was called &lt;a href=&#34;https://perlhacks.com/2012/03/you-must-hate-version-control-
systems/&#34;&gt;You Must Hate Version
Control
Systems&lt;/a&gt;. The title was taken from a Perl job ad from a company that
no-one seemed to want to work for. The person who posted the ad turned
up in the comments and tried to explain why he wrote that, but I don&amp;rsquo;t
think anyone was convinced. This was the one time that I regretted
that I couldn&amp;rsquo;t use a post&amp;rsquo;s comments in the book.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-is-perl-school-why-did-you-start-it-what-was-the-first-book&#34;&gt;What is Perl School? Why did you start it? What was the first book?&lt;/h4&gt;

&lt;p&gt;&lt;a href=&#34;https://perlschool.com&#34;&gt;Perl School&lt;/a&gt; was a brand that I started to
use in 2012 for some training I ran in London. I had theory that
people weren&amp;rsquo;t keeping their Perl knowledge up to date and many
employers weren&amp;rsquo;t keen on investing in training about what was &amp;ldquo;just a
scripting language.&amp;rdquo; So, I reasoned, if I ran low-cost training
courses at the weekend, people would come on them and the average
level of Perl knowledge in London would rise.&lt;/p&gt;

&lt;p&gt;I ran these courses for a year before putting them on ice. But I liked
the brand and knew that I wanted to use it again in the future.&lt;/p&gt;

&lt;p&gt;In 2015 I wrote a beginners&amp;rsquo; Perl tutorial for Udemy. They published
it on their site and I often pointed people at it. But a couple of
years later, I checked their site to find that a CSS upgrade had
rendered the page pretty much unreadable. I pointed this out to them
and after a bit of discussion, they told me that they weren&amp;rsquo;t going to
invest the time to fix it but said that I was welcome to publish it
elsewhere.&lt;/p&gt;

&lt;p&gt;At the same time I had been experimenting with building ebooks from
Markdown and had developed the pipeline that I still use today. So the
first Perl School book was the serendipitous meeting between my
experimental ebook pipeline and a long piece of text that I wanted to
get out to as many people as possible.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s called &lt;a href=&#34;https://perlschool.com/books/perl-taster/&#34;&gt;Perl Taster: Your First Two Hours With
Perl&lt;/a&gt;. I published it just
before the 2017 London Perl Workshop and announced it in a lighting
talk at that workshop. I invited other people to contribute books,
offering to help with the technical parts of getting them published.
John Davies approached me about the book that became &lt;a href=&#34;https://perlschool.com/books/selenium-perl/&#34;&gt;Selenium and
Perl&lt;/a&gt; and it&amp;rsquo;s just grown from there.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-was-your-experience-giving-low-cost-and-free-perl-training-in-the-uk&#34;&gt;What was your experience giving low-cost and free Perl training in the UK?&lt;/h4&gt;

&lt;p&gt;I&amp;rsquo;ve run Perl training at all levels in the UK. Five years ago I&amp;rsquo;d
still get two or three enquiries a year from companies who were
interested in training, but that&amp;rsquo;s all dried up. I can&amp;rsquo;t remember the
last time someone asked me about running a course for them.&lt;/p&gt;

&lt;p&gt;The Perl School courses were popular for a while. I&amp;rsquo;d get twenty or so
people giving up their Saturday and paying a small fee to get Perl
training. But after a year, the interest started to wane. I cancelled
the last one because I didn&amp;rsquo;t get enough attendees to make it
worthwhile.&lt;/p&gt;

&lt;p&gt;For many years I&amp;rsquo;ve run a free ninety-minute or two-hour course as
part of the London Perl Workshop. I always get a pretty good turn-out
for those. But, to be honest, that&amp;rsquo;s about the only place I can
guarantee much interest in Perl training in the UK these days.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;you-previously-wrote-the-print-books-data-munging-with-perl-https-www-manning-com-books-data-munging-with-perl-manning-press-and-template-toolkit-http-www-template-toolkit-org-book-html-o-reilly-associates-with-andy-wardley-and-darren-chamberlain-how-is-perl-school-s-process-different-than-what-you-experienced-with-those-publishers&#34;&gt;You previously wrote the print books &lt;a href=&#34;https://www.manning.com/books/data-munging-with-perl&#34;&gt;Data Munging with Perl&lt;/a&gt; (Manning Press) and &lt;a href=&#34;http://www.template-toolkit.org/book.html&#34;&gt;Template Toolkit&lt;/a&gt; (O&amp;rsquo;Reilly &amp;amp; Associates, with Andy Wardley and Darren Chamberlain). How is Perl School&amp;rsquo;s process different than what you experienced with those publishers?&lt;/h4&gt;

&lt;p&gt;I guess the main difference is that there&amp;rsquo;s a lot less process
involved with the Perl School books.&lt;/p&gt;

&lt;p&gt;With a traditional publisher, there are lots of departments involved.
The editor will want to know when the manuscript will be ready because
they will want to book time from technical reviewers and
proof-readers. They&amp;rsquo;ll also need to plan in designers and even book
printing time on the presses. All of that means there&amp;rsquo;s a lot of
pressure on the author to make a plan for getting the book written and
then to stick to that plan.&lt;/p&gt;

&lt;p&gt;With an ebook, it&amp;rsquo;s all a lot less structured. I largely rely on
authors to arrange their own technical reviewers. I&amp;rsquo;ll do a bit of
proof-reading. And we haven&amp;rsquo;t (as yet) used any designers—that
probably shows, to be honest.&lt;/p&gt;

&lt;p&gt;So I&amp;rsquo;m not going to pressure an author to finish a manuscript. When
you&amp;rsquo;re ready, I&amp;rsquo;ll steer you through turning your Markdown into an
ebook and then publishing it on Amazon. If it takes longer than you
expected, then so what?&lt;/p&gt;

&lt;p&gt;In many ways, I see parallels with the &lt;a href=&#34;http://theleanstartup.com&#34;&gt;Lean
Startup&lt;/a&gt; ideas of Eric Ries. We&amp;rsquo;re small
and we&amp;rsquo;re agile. If you come to me with a completed book, we might
well be able to get it on Amazon in a week or two. For a traditional
publisher, that time will be months.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-do-you-think-are-the-biggest-challenges-to-technical-publishing-today-how-does-something-like-perl-school-respond-to-that&#34;&gt;What do you think are the biggest challenges to technical publishing today? How does something like Perl School respond to that?&lt;/h4&gt;

&lt;p&gt;Traditional publishing is an expensive business. Publishers need to
make a lot of money just to break even on a book. I don&amp;rsquo;t know the
details, but they have to sell a certain number of copies in order to
make it worth publishing a book. And that, in turn, means that they
will rarely take a risk. For a technical publisher, that means only
publishing books about technologies that have reached a certain level
of usage.&lt;/p&gt;

&lt;p&gt;People are also buying fewer technical books. Technologies change
quickly and many books will be out of date before they get to the
bookshops. If you want up to date information about your favourite
technologies then you&amp;rsquo;re probably better off going to the developer&amp;rsquo;s
web site.&lt;/p&gt;

&lt;p&gt;For a publisher like Perl School, the economics are different. We have
far smaller costs and (as I mentioned before) we can get books in
customers&amp;rsquo; hands far more quickly.&lt;/p&gt;

&lt;p&gt;Large technical publishers have largely abandoned Perl. They just
don&amp;rsquo;t see that they would get the level of sales needed to justify a
new Perl book. Perl School is happy to take that risk—because, really,
it&amp;rsquo;s a tiny risk for us.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;what-are-your-personal-reading-preferences-which-device-do-you-like-what-size-screen-do-you-need-and-which-format-works-best-for-you&#34;&gt;What are your personal reading preferences? Which device do you like, what size screen do you need, and which format works best for you?&lt;/h4&gt;

&lt;p&gt;I do like a real book. But they take up too much space, so I&amp;rsquo;ve pretty
much completely stopped buying them over the last five years. I like
being able to access all of the ebook part of my library from a device
that I can carry in my pocket. One thing that would make me really
happy is a device that could rip my existing paper library to ebooks
in the same way that we all ripped our CDs to MP3s.&lt;/p&gt;

&lt;p&gt;Currently, I read ebooks on an 8&amp;rdquo; Amazon Kindle Fire. That&amp;rsquo;s just
bigger than a paperback and fits in a (large) pocket in the same way
that a book would. I also have a 10&amp;rdquo; Pixel Slate which I&amp;rsquo;ll often use
for reading in my house. I&amp;rsquo;m rather firmly locked into the Amazon
ebook ecosystem, so I prefer to find books in Mobi format—but I can
drive Calibre, so I&amp;rsquo;m happy to convert from other formats.&lt;/p&gt;

&lt;p&gt;I get mildly annoyed by web sites that promise me an ebook and then
deliver a PDF. PDFs are made to be read at a certain size and if
you&amp;rsquo;re reading them on a smaller screen it will either be too small to
read or you&amp;rsquo;ll need to scroll back and forth a lot. A proper ebook
format (like Mobi or ePub) will reformat pages for any combination of
screen size and font size.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;

&lt;h4 id=&#34;how-can-someone-write-a-book-for-perl-school-what-topics-do-you-think-would-be-most-interesting&#34;&gt;How can someone write a book for Perl School? What topics do you think would be most interesting?&lt;/h4&gt;

&lt;p&gt;Simply email me at hello@perlschool.com with your suggestions. I&amp;rsquo;ll
talk you though the technical side of getting the book written and
published on Amazon—it&amp;rsquo;s really not very hard.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;d pretty much consider any Perl-related topic. I would never have
thought of publishing books on Selenium or Cucumber, but John Davies
wrote them and I&amp;rsquo;ve published them. And they seem to be selling.&lt;/p&gt;

&lt;p&gt;But there are books I&amp;rsquo;d like to see. I&amp;rsquo;d love to publish books on the
various &amp;ldquo;Modern Perl&amp;rdquo; tools that we all use—Moose, DBIx::Class, things
like that—and all of Perl&amp;rsquo;s popular web frameworks.&lt;/p&gt;

&lt;p&gt;I think the one I&amp;rsquo;d most like to see is one that, in my head, is
called &amp;ldquo;Modern Core Perl&amp;rdquo;. It covers all of the important changes in
the core Perl language back to version 5.10. Basically, it&amp;rsquo;s a
tutorial based on all of the &lt;code&gt;perldelta&lt;/code&gt;s. I&amp;rsquo;ve thought about writing
it myself a few times, but I just don&amp;rsquo;t have the time.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s new on CPAN - April 2020</title>
      <link>https://www.perl.com/article/what-s-new-on-cpan-april-2020/</link>
      <pubDate>Wed, 20 May 2020 01:53:33 +0000</pubDate>
      
      <guid>https://www.perl.com/article/what-s-new-on-cpan-april-2020/</guid>
      <description>

&lt;p&gt;Welcome to &amp;ldquo;What&amp;rsquo;s new on CPAN&amp;rdquo;, a curated look at last month&amp;rsquo;s new CPAN uploads for your reading and programming pleasure. Enjoy!&lt;/p&gt;

&lt;h2 id=&#34;apis-apps&#34;&gt;APIs &amp;amp; Apps&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use the open, decentralizedc Matrix communication network with &lt;a href=&#34;https://metacpan.org/pod/Net::Matrix::Webhook&#34;&gt;Net::Matrix::Webhook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Call Docker CLI commands from Perl using &lt;a href=&#34;https://metacpan.org/pod/Docker::CLI::Wrapper&#34;&gt;Docker::CLI::Wrapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/InfluxDB::Client::Simple&#34;&gt;InfluxDB::Client::Simple&lt;/a&gt; is a lightweight InfluxDB client&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Termux::API&#34;&gt;Termux::API&lt;/a&gt; provides a Perly interface to the popular Android terminal emulator&lt;/li&gt;
&lt;li&gt;Get financial data via Yahoo Finance with &lt;a href=&#34;https://metacpan.org/pod/Yahoo::Finance&#34;&gt;Yahoo::Finance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;config-devops&#34;&gt;Config &amp;amp; Devops&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Grant Street Group added more healthcheck modules:

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::DBHCheck&#34;&gt;HealthCheck::Diagnostic::DBHCheck&lt;/a&gt; checks a database handle has read/write permissions&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::SFTP&#34;&gt;HealthCheck::Diagnostic::SFTP&lt;/a&gt; checks secure FTP access&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::WebRequest&#34;&gt;HealthCheck::Diagnostic::WebRequest&lt;/a&gt; checks HTTP/HTTPS connectivity&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Moo-ify DBIx::Class rows using &lt;a href=&#34;https://metacpan.org/pod/DBIx::Class::Moo::ResultClass&#34;&gt;DBIx::Class::Moo::ResultClass&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Data::Random::Structure::UTF8&#34;&gt;Data::Random::Structure::UTF8&lt;/a&gt; can fill a data structure with random UTF-8 data&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/JSON::Schema::Generate&#34;&gt;JSON::Schema::Generate&lt;/a&gt; generates JSON schemas from data structures&lt;/li&gt;
&lt;li&gt;Use named (instead of positional) placeholders with SQL queries via &lt;a href=&#34;https://metacpan.org/pod/SQL::Bind&#34;&gt;SQL::Bind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;development-version-control&#34;&gt;Development &amp;amp; Version Control&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Docker::Names::Random&#34;&gt;Docker::Names::Random&lt;/a&gt; generates random strings like Docker does for container names (e.g. &amp;ldquo;lazy_fermat&amp;rdquo;)&lt;/li&gt;
&lt;li&gt;A class based approach for scripting options: &lt;a href=&#34;https://metacpan.org/pod/Getopt::Class&#34;&gt;Getopt::Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Get simple, non-blocking IPC with &lt;a href=&#34;https://metacpan.org/pod/IPC::Simple&#34;&gt;IPC::Simple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/MooseX::amine&#34;&gt;MooseX::amine&lt;/a&gt; ++ for module naming, it let&amp;rsquo;s you examine the methods and properties of Moose objects&lt;/li&gt;
&lt;li&gt;Return from multiple blocks in one go with &lt;a href=&#34;https://metacpan.org/pod/Return::Deep&#34;&gt;Return::Deep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Test::Ability&#34;&gt;Test::Ability&lt;/a&gt; provides property-based testing routines&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/fs::Promises&#34;&gt;fs::Promises&lt;/a&gt; provides a promises interface to non-blocking file system operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;web&#34;&gt;Web&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Manage passwords in Dancer2 with Argon2 using &lt;a href=&#34;https://metacpan.org/pod/Dancer2::Plugin::Argon2&#34;&gt;Dancer2::Plugin::Argon2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use the Minion job queue in your Dancer2 apps with &lt;a href=&#34;https://metacpan.org/pod/Dancer2::Plugin::Minion&#34;&gt;Dancer2::Plugin::Minion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Override any method in your Kelp application with &lt;a href=&#34;https://metacpan.org/pod/KelpX::Hooks&#34;&gt;KelpX::Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Mojo::Log::Role::Color&#34;&gt;Mojo::Log::Role::Color&lt;/a&gt; adds color to your interactive mojo logs&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Mojo::UserAgent::Role::Signature&#34;&gt;Mojo::UserAgent::Role::Signature&lt;/a&gt; automatically signs request transactions&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Multipart::Encoder&#34;&gt;Multipart::Encoder&lt;/a&gt; is an encoder for mime-type multipart/form-data.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s new on CPAN - March 2020</title>
      <link>https://www.perl.com/article/what-s-new-on-cpan-march-2020/</link>
      <pubDate>Wed, 29 Apr 2020 01:05:57 +0000</pubDate>
      
      <guid>https://www.perl.com/article/what-s-new-on-cpan-march-2020/</guid>
      <description>

&lt;p&gt;Welcome to &amp;ldquo;What&amp;rsquo;s new on CPAN&amp;rdquo;, a curated look at last month&amp;rsquo;s new CPAN uploads for your reading and programming pleasure. Enjoy!&lt;/p&gt;

&lt;h2 id=&#34;apis-apps&#34;&gt;APIs &amp;amp; Apps&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get a colorful calendar in the terminal with &lt;a href=&#34;https://metacpan.org/pod/week&#34;&gt;App::week&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Google::reCAPTCHA::v3&#34;&gt;Google::reCAPTCHA::v3&lt;/a&gt; is another Google captcha module&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/GraphQL::Client&#34;&gt;GraphQL::Client&lt;/a&gt; … is a GraphQL client&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Masscan::Scanner&#34;&gt;Masscan::Scanner&lt;/a&gt; makes it easy to use the masscan port scanner.&lt;/li&gt;
&lt;li&gt;Make non-blocking requests to LastFM with &lt;a href=&#34;https://metacpan.org/pod/Mojo::WebService::LastFM&#34;&gt;Mojo::WebService::LastFM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use Telegram&amp;rsquo;s Bot API with &lt;a href=&#34;https://metacpan.org/pod/Net::API::Telegram&#34;&gt;Net::API::Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Net::OpenVAS&#34;&gt;Net::OpenVAS&lt;/a&gt; let&amp;rsquo;s you program Greenbone&amp;rsquo;s OpenVAS platform with Perl&lt;/li&gt;
&lt;li&gt;Use Elasticsearch 6.x APIs with &lt;a href=&#34;https://metacpan.org/pod/Search::Elasticsearch::Client::6_0&#34;&gt;Search::Elasticsearch::Client::6_0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;config-devops&#34;&gt;Config &amp;amp; Devops&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Block::NJH&#34;&gt;Block::NJH&lt;/a&gt; is interesting; add it to your CPAN distribution to &amp;ldquo;prevent your tests from running on NJH&amp;rsquo;s broken smokers&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Config::Structured&#34;&gt;Config::Structured&lt;/a&gt; provides &amp;ldquo;generalized and structured configuration value access&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Ping a database handle to check its health using &lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::DBHPing&#34;&gt;HealthCheck::Diagnostic::DBHPing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/HealthCheck::Diagnostic::FilePermissions&#34;&gt;HealthCheck::Diagnostic::FilePermissions&lt;/a&gt; checks filepaths for expected permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;data&#34;&gt;Data&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/DB::Object&#34;&gt;DB::Object&lt;/a&gt; is a database abstraction built on top of DBI&lt;/li&gt;
&lt;li&gt;Inspect DBIC objects in a compact format using &lt;a href=&#34;https://metacpan.org/pod/Data::Tersify::Plugin::DBIx::Class&#34;&gt;Data::Tersify::Plugin::DBIx::Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/MIME::Base32::XS&#34;&gt;MIME::Base32::XS&lt;/a&gt; is a faster Base32 encoder/decoder&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Statistics::Covid&#34;&gt;Statistics::Covid&lt;/a&gt; fetches and manages Covid-19 statistics&lt;/li&gt;
&lt;li&gt;Get a Postgresql mock server for testing via &lt;a href=&#34;https://metacpan.org/pod/Test::PostgreSQL::Docker&#34;&gt;Test::PostgreSQL::Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Bind Perl data structures into XML with &lt;a href=&#34;https://metacpan.org/pod/XML::BindData&#34;&gt;XML::BindData&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/XML::Minifier&#34;&gt;XML::Minifier&lt;/a&gt; is a configurable XML minifier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;development-version-control&#34;&gt;Development &amp;amp; Version Control&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Devel::Wherefore&#34;&gt;Devel::Wherefore&lt;/a&gt; helps debug Perl: &amp;ldquo;Where the heck did these subroutines come from?&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Create relative symbolic links &lt;a href=&#34;https://metacpan.org/pod/File::Symlink::Relative&#34;&gt;File::Symlink::Relative&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Module::Generic&#34;&gt;Module::Generic&lt;/a&gt; is another class library, it uses AUTOLOAD for getter/setter methods&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/new&#34;&gt;new&lt;/a&gt; saves you from typing module names twice in one liners&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;science-mathematics&#34;&gt;Science &amp;amp; Mathematics&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Bio::DB::Taxonomy::sqlite&#34;&gt;Bio::DB::Taxonomy::sqlite&lt;/a&gt; stores and manages NCBI data using sqlite&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Math::Polynomial::Chebyshev&#34;&gt;Math::Polynomial::Chebyshev&lt;/a&gt; creates Chebyshev polynomials&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;web&#34;&gt;Web&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Store Catalyst sessions in Redis with &lt;a href=&#34;https://metacpan.org/pod/Catalyst::Plugin::Session::Store::RedisFast&#34;&gt;Catalyst::Plugin::Session::Store::RedisFast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Not a traditional distribution, but &lt;a href=&#34;https://metacpan.org/pod/Mojo::Server::AWSLambda&#34;&gt;Mojo::Server::AWSLambda&lt;/a&gt; contains a simple example of how to define an AWS Lambda function which uses Mojo&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/pod/Mojolicious::Plugin::Sticker&#34;&gt;Mojolicious::Plugin::Sticker&lt;/a&gt; combines Mojo apps into a single app&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Observing Coronavirus Pandemic with Raku</title>
      <link>https://www.perl.com/article/observing-coronavirus-with-raku/</link>
      <pubDate>Thu, 02 Apr 2020 08:45:00 +0000</pubDate>
      
      <guid>https://www.perl.com/article/observing-coronavirus-with-raku/</guid>
      <description>

&lt;p&gt;Every few years a new unknown virus pops up and starts spreading around the globe. This year, the situation with COVID-19 is different not only because of the nature of the virus but also because of the Internet. Whilst we have instant access to new information (which is often alarmist in tone) we also have the ability to access data for ourselves.&lt;/p&gt;

&lt;p&gt;Johns Hopkins University Center for Systems Science and Engineering synthesizes COVID-19 data from different sources, and displays it on their &lt;a href=&#34;https://gisanddata.maps.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6&#34;&gt;online dashboard&lt;/a&gt;. They also publish daily updates in CSV files on &lt;a href=&#34;https://github.com/CSSEGISandData/COVID-19&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I decided to ingest their CSV data and display it using different visualizations to reduce panic and provide a way to quickly see real numbers and trends. The result is the website &lt;a href=&#34;https://covid.observer&#34;&gt;covid.observer&lt;/a&gt;. The source files are available in the GitHub &lt;a href=&#34;https://github.com/ash/covid.observer&#34;&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For years Perl has been known for BioPerl. Let’s see what Raku can bring to society as its great at manipulating text data. The heart of the site is a Raku program and a few modules that parse data and create static HTML pages.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img src=&#34;https://www.perl.com/images/observing-coronavirus-with-raku/covid-observer.png&#34; alt=&#34;covid-observer&#34; /&gt;
&lt;br /&gt;
&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m going to show you a few of the most useful features that Raku offers to developers.&lt;/p&gt;

&lt;h2 id=&#34;the-main-function&#34;&gt;The &lt;code&gt;MAIN&lt;/code&gt; function&lt;/h2&gt;

&lt;p&gt;The program works in three modes: parsing population data, getting updates from the COVID raw data, and generating HTML files. Raku gives us a very handy way to process command line arguments by defining different variants of the &lt;code&gt;MAIN&lt;/code&gt; function. Each variant is mapped to different command line parameters, and Raku automatically dispatches to the matched variant, which helps me to run the program in the desired mode.&lt;/p&gt;

&lt;p&gt;Here are the variants:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;multi &lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MAIN&lt;/span&gt;(&amp;#39;population&amp;#39;) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}

multi &lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MAIN&lt;/span&gt;(&amp;#39;fetch&amp;#39;) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}

multi &lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MAIN&lt;/span&gt;(&amp;#39;generate&amp;#39;) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We don’t need to parse the command-line options ourselves, nor use any modules such as &lt;code&gt;Getopt::Long&lt;/code&gt; to do it for us. Moreover, Raku emits &amp;ldquo;usage&amp;rdquo; help text if the program is run with incorrect or missing arguments:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;$ ./covid.raku
Usage:
  ./covid.raku population
  ./covid.raku fetch
  ./covid.raku generate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Salve J. Nilsen &lt;a href=&#34;https://github.com/ash/covid.observer/pull/5&#34;&gt;proposed to add&lt;/a&gt; another &lt;code&gt;MAIN&lt;/code&gt; function that prints the SQL commands for initializing the database. This example shows how how to define Boolean flags for command line options:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;multi &lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MAIN&lt;/span&gt;(&amp;#39;setup&amp;#39;, Bool :$force=False, Bool :$verbose=False) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note the &lt;code&gt;:&lt;/code&gt; before the parameter name. We’ll see it again later.&lt;/p&gt;

&lt;p&gt;An additional POD comment can be added before each version of the function to print a better usage description, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#| Fetch the latest data and rebuild the database&lt;/span&gt;
multi &lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;MAIN&lt;/span&gt;(&amp;#39;fetch&amp;#39;) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the program prints a more helpful usage message:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;Usage:
  ./covid.raku population -- Parse population CSV files
  ./covid.raku fetch -- Fetch the latest data and rebuild the database
  ./covid.raku generate -- Generate the website&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;reduction-operators&#34;&gt;Reduction operators&lt;/h2&gt;

&lt;p&gt;Reduction operators are really useful. Let me remind you what a reduction operator is. It&amp;rsquo;s actually a meta-operator: an infix operator surrounded by square brackets.&lt;/p&gt;

&lt;p&gt;In the program the reduction operator is widely used for computing totals across the data sets (e.g. for the World, or across Chinese provinces). Let us examine a few cases of increasing complexity:&lt;/p&gt;

&lt;p&gt;First there’s a simple hash, and we need to add up its values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; %data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
    IT &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;59_138&lt;/span&gt;,
    CN &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;81_397&lt;/span&gt;,
    ES &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;28_768&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $total &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;] %data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values;
say $total; &lt;span style=&#34;color:#75715e&#34;&gt;# 169303&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the classic use case for the reduction operator. What I &lt;a href=&#34;https://andrewshitov.com/2020/03/16/a-couple-of-syntax-sweets-in-raku/&#34;&gt;noticed&lt;/a&gt; during the work is that the &lt;code&gt;[-]&lt;/code&gt; construct helps when you need to reduce some value by a few other values:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; %data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
    confirmed &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt;,
    failed    &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;,
    recovered &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt;;

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $active &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;] %data&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;confirmed recovered failed&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;;
say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$active active cases&amp;#34;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using a hash slice in the form of &lt;code&gt;%h&amp;lt;a b c&amp;gt;&lt;/code&gt; also helps to make the code more compact. Compare this with the straightforward approach:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $active &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; %data&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; %data&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;failed&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; %data&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;recovered&amp;gt;&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;filtering-data&#34;&gt;Filtering data&lt;/h2&gt;

&lt;p&gt;For our second case, the hash values are not scalars but hashes themselves. The &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; hyperoperator can be used to extract deeply located data. Let me demonstrate this on a simplified data fragment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; %data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
    IT &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; {
        confirmed &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;59_138&lt;/span&gt;,
        population &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;61&lt;/span&gt;, &lt;span style=&#34;color:#75715e&#34;&gt;# millions&lt;/span&gt;
    },
    CN &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; {
        confirmed &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;81_397&lt;/span&gt;,
        population &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1434&lt;/span&gt;
    },
    ES &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; {
        confirmed &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;28_768&lt;/span&gt;,
        population &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;47&lt;/span&gt;,
    };

&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $total &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;] %data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt;;
say $total; &lt;span style=&#34;color:#75715e&#34;&gt;# 169303&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An alternative and cleaner way is using the &lt;code&gt;map&lt;/code&gt; method to access the data:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $total2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;] %data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;map: &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt;;
say $total2; &lt;span style=&#34;color:#75715e&#34;&gt;# 169303&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, to exclude a country from the results, you can &lt;code&gt;grep&lt;/code&gt; the keys in-place:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; %x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; %data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;grep: &lt;span style=&#34;color:#f92672&#34;&gt;*.&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;ne&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $excl2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;] %x&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;map: &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt;;
say $excl2; &lt;span style=&#34;color:#75715e&#34;&gt;# 87906&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that calling the hash&amp;rsquo;s &lt;code&gt;grep&lt;/code&gt; method is much handier than trying to loop over the keys and filter them:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $excluding&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;china &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
    [&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;] %data{%data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;keys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;grep: &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;ne&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;}&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;map: &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt;;
say $excluding&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;china; &lt;span style=&#34;color:#75715e&#34;&gt;# 87906&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;hyper-operators&#34;&gt;Hyper operators&lt;/h2&gt;

&lt;p&gt;In the previous section I showed how to apply the same action to each element of a list using &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;. Now let us take a look at a real example of how I used the hyper operator &lt;code&gt;&amp;gt;&amp;gt;-&amp;gt;&amp;gt;&lt;/code&gt; to compute the deltas of number series:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; @confirmed &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;70&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;150&lt;/span&gt;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; @delta &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; @confirmed[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;..*&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;-&amp;gt;&amp;gt;&lt;/span&gt; @confirmed;
say @delta; &lt;span style=&#34;color:#75715e&#34;&gt;# [10 20 30 80]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The array contains a series of values for the given period of time. The task is to compute how many new cases happen in each day. Instead of using a loop, it is possible to simply ‘subtract‘ an array from itself but shifted by one element.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;gt;&amp;gt;-&amp;gt;&amp;gt;&lt;/code&gt; operator takes two data series: the slice &lt;code&gt;@confirmed[1..*]&lt;/code&gt; of the original data without the first element, and the original &lt;code&gt;@confirmed&lt;/code&gt; array. For a given binary operator (&lt;code&gt;-&lt;/code&gt; in this example), you can construct four hyper operators: &lt;code&gt;&amp;gt;&amp;gt;-&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;-&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;-&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;-&amp;lt;&amp;lt;&lt;/code&gt;. The chosen form allows us to ignore the extra item at the end of &lt;code&gt;@confirmed&lt;/code&gt; when it is applied against &lt;code&gt;@confirmed[1..*]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;junctions&#34;&gt;Junctions&lt;/h2&gt;

&lt;p&gt;Let me demonstrate a way of using the junction operator &lt;code&gt;|&lt;/code&gt; which I discovered recently. It chooses the ending for the given ordinal number:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;..&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;31&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; $day {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $ending &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; given $day {
        when &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;31&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;st&amp;#39;&lt;/span&gt;}
        when &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;    {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;nd&amp;#39;&lt;/span&gt;}
        when &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;23&lt;/span&gt;    {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;rd&amp;#39;&lt;/span&gt;}
        default      {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;th&amp;#39;&lt;/span&gt;}
    }

    say &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;$day$ending&amp;#34;&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;when&lt;/code&gt; blocks catch the corresponding numbers that need special endings. Junctions such as &lt;code&gt;1|21|31&lt;/code&gt; are more elegant than a regular expression or a chain of comparisons.&lt;/p&gt;

&lt;h2 id=&#34;optional-and-named-parameters&#34;&gt;Optional and named parameters&lt;/h2&gt;

&lt;p&gt;Parameter processing is simple in Raku. This function accepts two positional hash parameters:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chart&lt;/span&gt;-daily(%countries, %totals) {
    &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I can easily add optional named parameters:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;sub&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chart&lt;/span&gt;-daily(%countries, %totals, :$cc?, :$cont?, :$exclude?) {
   &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A colon before the name makes the parameter named, and the question mark makes it optional. I am using this to modify the behavior of the same statistical function for aggregating data over the whole World, the continents, or to exclude a single country or a region:&lt;/p&gt;

&lt;p&gt;Generating data for the whole World:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;chart&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;daily(%countries, %per&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;day);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For a single country:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $cc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;;
chart&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;daily(%countries, %per&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;day, :$cc);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For a continent:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $cont &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Europe&amp;#39;&lt;/span&gt;;
chart&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;daily(%countries, %per&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;day, :$cont);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;World data excluding China:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;chart&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;daily(%countries, %per&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;day, exclude &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Getting data for China without its most affected province:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;chart&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;daily(%countries, %per&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;day, cc &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN&amp;#39;&lt;/span&gt;, exclude &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CN/HB&amp;#39;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;a-built-in-template-engine&#34;&gt;A built-in template engine&lt;/h2&gt;

&lt;p&gt;The project generates more than 200 HTML files, so templating is an important part of it. Fortunately Raku has a great out-of-the-box templating mechanism, which is much more powerful than simple variable interpolation.&lt;/p&gt;

&lt;p&gt;A minimal example is substituting variables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; qq:to&lt;span style=&#34;color:#e6db74&#34;&gt;/HTML/&lt;/span&gt;;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;div id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;countries-list&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
        $html
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    HTML&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By the way, notice that Raku lets you keep the indentation of a multi-line string by simply indenting its closing symbol. No extra spaces at the beginning of the lines will appear in the result.&lt;/p&gt;

&lt;p&gt;A more exciting thing is that you can embed Raku code blocks into strings, and those blocks can contain any logic you need to make a right decision somewhere in the middle of the template:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;my&lt;/span&gt; $content &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; qq:to&lt;span style=&#34;color:#e6db74&#34;&gt;/HTML/&lt;/span&gt;;
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Coronavirus in {$country&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;name}&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;div class&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;affected&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
        {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; $chart2data&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt; {
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Affected 1 of every &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;
                    fmtnum((&lt;span style=&#34;color:#ae81ff&#34;&gt;1_000_000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; $population &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;
                        $chart2data&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;confirmed&amp;gt;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;round())
            }
            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
                &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Nobody affected&amp;#39;&lt;/span&gt;
            }
        }
    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    HTML&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, the string builds itself depending on data. For each generated country, the string ’chooses‘ which phrase to embed and how to format the number. The &lt;code&gt;if&lt;/code&gt; block is a relatively big chunk of Raku code that generates a string, which is used in place of the whole block in curly braces. Thus, inside this embedded code block you can freely manipulate data from the outside code.&lt;/p&gt;

&lt;h2 id=&#34;afterword&#34;&gt;Afterword&lt;/h2&gt;

&lt;p&gt;I must say that it is quite exciting to use Raku for a real project. As you can see from the examples, many of its ‘strange‘ features demonstrate how useful they are in different circumstances. Examine the code in the &lt;a href=&#34;https://github.com/ash/covid.observer&#34;&gt;GitHub repository&lt;/a&gt; and follow the updates about the site &lt;a href=&#34;https://andrewshitov.com/category/covid-19/&#34;&gt;on my blog&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>

