Shlomi Fish avatar Shlomi Fish committed c79f14d

Add some tests.

Comments (0)

Files changed (4)

XML-Grammar-Vered/lib/XML/Grammar/Vered.pm

 
 
 has '+to_docbook_xslt_transform_basename' =>
-    (docbook => 'vered-xml-to-docbook.xslt');
+    (default => 'vered-xml-to-docbook.xslt');
 
 has '_mode' => (is => 'rw', init_arg => 'mode');
 has '_output_mode' => (is => 'rw', init_arg => 'output_mode',);

XML-Grammar-Vered/t/data/system-tests-1/expected-docbook/bad-elements.docbook.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<db:article xmlns:db="http://docbook.org/ns/docbook" xmlns:vrd="http://www.shlomifish.org/open-source/projects/XML-Grammar/Vered/" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="index" xml:lang="en-GB" version="5.0">
+  <db:info>
+    <db:title>Perl Elements to Avoid</db:title>
+  </db:info>
+  <db:section role="introduction" xml:id="intro">
+    <db:info>
+      <db:title>Introduction</db:title>
+    </db:info>
+    <db:para>
+Often when people ask for help with Perl code, they show Perl code that
+suffers from many bad or outdated elements. This is expected, as there
+are many bad Perl tutorials out there, and lots of bad code that people
+have learned from, but it is still not desirable. In order to not get
+"yelled at" for using these, here is the document of the bad elements that
+people tend to use and some better practices that should be used instead.
+</db:para>
+    <db:para>
+A book I read said, that as opposed to most previous idea systems, they
+were trying to <db:emphasis role="bold">liquidate negatives</db:emphasis> instead of instilling positives
+in people. So in the spirit of liquidating negatives, this tutorial-in-reverse
+aims to show you what <db:emphasis role="bold">not to do</db:emphasis>.
+</db:para>
+    <db:para>
+<db:emphasis role="bold">Note:</db:emphasis> Please don't think this advice is meant as gospel.
+There are some instances where one can expect to deviate from it, and a lot
+of it can be considered only my own opinion. I tried to filter the various
+advice I found in the <db:link xlink:href="#sources_of_advice">sources for this advice</db:link>
+and get rid of things that are a matter of taste or not so critical, or have
+arguments here or there (so-called <db:link xlink:href="http://bikeshed.com/">colour of
+the bike shed arguments</db:link>), but some of the advice here may still be
+controversial.
+</db:para>
+  </db:section>
+  <db:section xml:id="bad-elements">
+    <db:info>
+      <db:title>The List of Bad Elements</db:title>
+    </db:info>
+    <db:section role="item" xml:id="no-indentation">
+      <db:info>
+        <db:title>No Indentation</db:title>
+      </db:info>
+      <db:para>
+<db:link xlink:href="http://en.wikipedia.org/wiki/Indent_style">Indentation</db:link> means
+that the contents of every block are promoted from their containing environment
+by using a shift of some space. This makes the code easier to read and follow.
+</db:para>
+      <db:para>
+Code without indentation is harder to read and so should be avoided.
+<db:link xlink:href="http://en.wikipedia.org/wiki/Indent_style">The Wikipedia article</db:link>
+lists several styles - pick one and follow it.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="no-strict-and-warnings">
+      <db:info>
+        <db:title>No "use strict;" and "use warnings;"</db:title>
+      </db:info>
+      <db:para>
+All modern Perl code should have the "use strict;" and "use warnings;" pragmas
+that prevent or warn against misspelling variable names, using undefined
+values, and other bad practices. So start your code (in every file) with this:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+use strict;
+use warnings;
+</db:programlisting>
+      <db:para>
+Or:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+package MyModule;
+use strict;
+use warnings;
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="open-function-style">
+      <db:info>
+        <db:title>Correct style for using the open function</db:title>
+      </db:info>
+      <db:para>
+<db:link xlink:href="http://perldoc.perl.org/functions/open.html">The open function</db:link>
+is used to open files, sub-processes, etc. The correct style for it is:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+open my $input_fh, "&lt;", $input_filename
+    or die "Could not open '$input_filename' - $!";
+</db:programlisting>
+      <db:para>
+some <db:emphasis role="bold">wrong</db:emphasis>, insecure and/or outdated styles are:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+# Bareword filehandle (type glob), two arguments open (insecure) and no
+# error handling
+open INPUT, "&lt;$filename";
+# Also opens from $INPUT.
+open INPUT;
+# Bareword filehandle with three args open and no exception thrown.
+open INPUT, "&lt;", $filename;
+# Bareword filehandle with two-args open and exception (rare, but possible):
+open INPUT, "&lt;$filename"
+    or die "Cannot open $filename - $!";
+# Lexical file handle with two-args open (instead of three-args open)
+# and no exception
+open my $input_fh, "&lt;$filename";
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="calling-variables-file">
+      <db:info>
+        <db:title>Calling variables "file"</db:title>
+      </db:info>
+      <db:para>
+Some people call their variables "file". However, file can mean either
+<db:link xlink:href="http://en.wikipedia.org/wiki/File_descriptor">file handles</db:link>,
+file names, or the contents of the file. As a result, this should be avoided
+and one can use the abbreviations "fh" for file handle, or "fn" for filenames
+instead.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="identifiers-without-underscores">
+      <db:info>
+        <db:title>Identifiers without underscores</db:title>
+      </db:info>
+      <db:para>
+Some people name their identifiers as several words all in lowercase and
+not separated by underscores ("_"). As a result, this makes the code harder
+to read. So instead of:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my @namesofpresidents;
+</db:programlisting>
+      <db:para>
+Say:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my @names_of_presidents;
+</db:programlisting>
+      <db:para>
+Or maybe:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my @presidents_names;
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="prototypes">
+      <db:info>
+        <db:title>Don't use prototypes for subroutines</db:title>
+      </db:info>
+      <db:para>
+Some people are tempted to declare their subroutines using
+<db:code>sub my_function ($$@)</db:code>, with the signature of the accepted parameter
+types, which is called a prototype. However, this tends to break code more
+often than not, and should be avoided.
+</db:para>
+      <db:para>
+If you're looking for parameter lists to functions and methods, take a look
+at <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Devel-Declare">Devel-Declare</db:link> from
+CPAN. But don't use prototypes.
+</db:para>
+      <db:para>
+For more information, see:
+</db:para>
+      <db:orderedlist>
+<db:listitem>
+<db:para>
+<db:link xlink:href="https://www.socialtext.net/perl5/prototype">Discussion on the Perl 5 Wiki</db:link>
+</db:para>
+</db:listitem>
+<db:listitem>
+<db:para>
+<db:link xlink:href="http://stackoverflow.com/questions/297034/why-are-perl-5s-function-prototypes-bad">“Why
+are Perl 5’s function prototypes bad?”</db:link> on Stack Overflow.
+</db:para>
+</db:listitem>
+</db:orderedlist>
+    </db:section>
+    <db:section role="item" xml:id="ampersand-in-subroutine-calls">
+      <db:info>
+        <db:title>Ampersand in Subroutine Calls</db:title>
+      </db:info>
+      <db:para>
+One should not call a subroutine using <db:code>&amp;myfunc(@args)</db:code> unless
+you're sure that is what you want to do (like overriding prototypes). Normally
+saying <db:code>myfunc(@args)</db:code> is better.
+</db:para>
+      <db:para>
+For more information see
+<db:link xlink:href="https://www.socialtext.net/perl5/subroutines_called_with_the_ampersand">the
+relevant page</db:link> on the Perl 5 Wiki.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="assigning-from-dollar-underscore">
+      <db:info>
+        <db:title>Assigning from $_</db:title>
+      </db:info>
+      <db:para>
+Some people write code like the following:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+while (&lt;$my_fh&gt;)
+{
+    my $line = $_;
+    # Do something with $line…
+}
+</db:programlisting>
+      <db:para>
+Or:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+foreach (@users)
+{
+    my $user = $_;
+    # Process $user…
+}
+</db:programlisting>
+      <db:para>
+However, you can easily assign the explicit and lexical variables in the
+loop's opening line like so:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+while (my $line = &lt;$my_fh&gt;)
+{
+    # Do something with $line…
+}
+</db:programlisting>
+      <db:para>
+and:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+foreach my $user (@users)
+{
+    # Process $user…
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="foreach-lines">
+      <db:info>
+        <db:title>Using "foreach" on lines</db:title>
+      </db:info>
+      <db:para>
+Some people may be tempted to write this code:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+foreach my $line (&lt;$my_file_handle&gt;)
+{
+    # Do something with $line.
+}
+</db:programlisting>
+      <db:para>
+This code appears to work but what it does is read the entire contents of the
+file pointed by $my_file_handle into a (potentially long) list of lines, and
+then iterate over them. This is inefficient. In order to read one line
+at a time, use this instead:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+while (my $line = &lt;$my_file_handle&gt;)
+{
+    # Do something with $line.
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="string-notation">
+      <db:info>
+        <db:title>String Notation</db:title>
+      </db:info>
+      <db:para>
+Perl has a flexible way to write strings and other delimiters, and you should
+utilize it for clarity. If you find yourself writing long strings, write them
+as <db:link xlink:href="http://en.wikipedia.org/wiki/Here_document">here-documents</db:link>:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my $long_string_without_interpolation = &lt;&lt;'EOF';
+Hello there. I am a long string.
+I am part of the string.
+And so am I.
+EOF
+</db:programlisting>
+      <db:para>
+There are also <db:code>&lt;&lt;"EOF"</db:code> for strings with interpolation
+and <db:code>&lt;&lt;`EOF`</db:code> for trapping command output. Make sure you never
+use bareword here documents <db:code>&lt;&lt;EOF</db:code> which are valid syntax,
+but many people are never sure whether they are <db:code>&lt;&lt;"EOF"</db:code> or
+<db:code>&lt;&lt;'EOF'</db:code>.
+</db:para>
+      <db:para>
+If your strings are not too long but contain the special characters that
+correspond with the default delimiters (e.g: <db:code>'</db:code>, <db:code>"</db:code>,
+<db:code>`</db:code>, <db:code>/</db:code> etc.), then you can use the initial letter followed
+by any arbitrary delimiter notation: <db:code>m{\A/home/sophie/perl}</db:code>,
+<db:code>q/My name is 'Jack' and I called my dog "Diego"./</db:code>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="slurp">
+      <db:info>
+        <db:title>Slurping a file (i.e: Reading it all into memory)</db:title>
+      </db:info>
+      <db:para>
+One can see several bad ways to read a file into memory in Perl. Among them
+are:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Not portable and suffers from possible
+# shell code injection.
+my $contents = `cat $filename`;
+# Wasteful of CPU and memory:
+my $contents = join("", &lt;$fh&gt;);
+# Even more so:
+my $contents = '';
+while (my $line = &lt;$fh&gt;)
+{
+    $contents .= $line;
+}
+</db:programlisting>
+      <db:para>
+You should avoid them all. Instead the proper way to read an entire file
+into a long string is to either use CPAN distributions for that such as
+<db:link role="cpan_dist" xlink:href="http://metacpan.org/release/File-Slurp">File-Slurp</db:link> or
+<db:link role="cpan_dist" xlink:href="http://metacpan.org/release/IO-All">IO-All</db:link>, or alternatively
+write down the following function and use it:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+sub _slurp
+{
+    my $filename = shift;
+    open my $in, '&lt;', $filename
+        or die "Cannot open '$filename' for slurping - $!";
+    local $/;
+    my $contents = &lt;$in&gt;;
+    close($in);
+    return $contents;
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="paragraphs">
+      <db:info>
+        <db:title>Write code in Paragraphs using Empty Lines</db:title>
+      </db:info>
+      <db:para>
+If one of your blocks is long, split it into "code paragraphs", with empty
+lines between them and with each paragraph doing one thing. Then, it may be a
+good idea to precede each paragraph with a comment explaining what it does, or
+to extract it into its own function or method.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="io-socket">
+      <db:info>
+        <db:title>Use IO::Socket and friends instead of lower-level calls</db:title>
+      </db:info>
+      <db:para>
+One should use <db:link role="cpan_module" xlink:href="http://metacpan.org/module/IO::Socket">the IO::Socket</db:link> family of
+modules for networking Input/Output instead of the
+lower-level socket()/connect()/bind()/etc. calls. As of this writing,
+<db:link role="perldoc" xlink:href="http://perldoc.perl.org/perlipc.html">perlipc</db:link> contains outdated information demonstrating how
+to use the lower-level API which is not recommended.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="subroutine-arguments">
+      <db:info>
+        <db:title>Subroutine Arguments Handling</db:title>
+      </db:info>
+      <db:para>
+The first thing to know about handling arguments for subroutines is to avoid
+referring to them directly by index. Imagine you have the following code:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+sub my_function
+{
+    my $first_name = $_[0];
+    my $street = $_[1];
+    my $city = $_[2];
+    my $country = $_[3];
+    .
+    .
+    .
+}
+</db:programlisting>
+      <db:para>
+Now, what if you want to add <db:code>$last_name</db:code> between <db:code>$first_name</db:code>
+and <db:code>$street</db:code>?
+You'll have to promote all the indexes after it! Moreover, this scheme
+is error-prone and you may reuse the same index more than once, or
+miss some indexes.
+</db:para>
+      <db:para>
+Instead do either:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+sub my_function
+{
+    my $first_name = shift;
+    my $street = shift;
+    my $city = shift;
+    my $country = shift;
+    .
+    .
+    .
+}
+</db:programlisting>
+      <db:para>
+Or:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+sub my_function
+{
+    my ($first_name, $street, $city, $country) = @_;
+    .
+    .
+    .
+}
+</db:programlisting>
+      <db:para>
+The same thing holds for unpacking <db:code>@ARGV</db:code>, the array containing the
+command-line arguments for a Perl program, or any other array. Don't use
+<db:code>$ARGV[0]</db:code>, <db:code>$ARGV[1]</db:code> etc. directly, but instead unpack
+<db:code>@ARGV</db:code> using the methods given above. For processing
+command line arguments, you should also consider using
+<db:link role="cpan_module" xlink:href="http://metacpan.org/module/Getopt::Long">Getopt::Long</db:link>.
+</db:para>
+      <db:section role="item" xml:id="clobbering-arrays-or-hashes">
+        <db:info>
+          <db:title>Don’t clobber arrays or hashes</db:title>
+        </db:info>
+        <db:para>
+Often people ask how to pass arrays or hashes to subroutines. The answer is
+that the right way to do it is to pass them as a reference as an argument
+to the subroutine:
+</db:para>
+        <db:programlisting xml:space="preserve" language="perl">
+sub calc_polynomial
+{
+    my ($x, $coefficients) = @_;
+    my $x_power = 1;
+    my $result = 0;
+    foreach my $coeff (@{$coefficients})
+    {
+        $result += $coeff * $x_power;
+    }
+    continue
+    {
+        $x_power *= $x;
+    }
+    return $result;
+}
+print "(4*x^2 + 2x + 1)(x = 5) = ", calc_polynomial(5, [1, 2, 4]);
+</db:programlisting>
+        <db:para>
+You shouldn't clobber the subroutine's arguments list with entire arrays
+or hashes (e.g: <db:code>my_func(@array1, @array2);</db:code> or
+<db:code>my_func(%myhash, $scalar)</db:code> ), as this will make it difficult to
+extract from <db:code>@_</db:code>.
+</db:para>
+      </db:section>
+      <db:section role="item" xml:id="named-parameters">
+        <db:info>
+          <db:title>Named Parameters</db:title>
+        </db:info>
+        <db:para>
+If the number of parameters that your subroutine accepts gets too long, or
+if you have too many optional parameters, make sure you convert it to use
+named arguments. The standard way to do it is to pass a hash reference or
+a hash of arguments to the subroutine:
+</db:para>
+        <db:programlisting xml:space="preserve" language="perl">
+sub send_email
+{
+    my $args = shift;
+    my $from_address = $args-&gt;{from};
+    my $to_addresses = $args-&gt;{to};
+    my $subject = $args-&gt;{subject};
+    my $body = $args-&gt;{body};
+    .
+    .
+    .
+}
+send_email(
+    {
+        from =&gt; 'shlomif@perl-begin.org',
+        to =&gt; ['shlomif@perl-begin.org', 'sophie@perl-begin.org'],
+        subject =&gt; 'Perl-Begin.org Additions',
+        .
+        .
+        .
+    }
+);
+</db:programlisting>
+      </db:section>
+    </db:section>
+    <db:section role="item" xml:id="chop">
+      <db:info>
+        <db:title>Avoid using chop() to trim newlines characters from lines</db:title>
+      </db:info>
+      <db:para>
+Don't use <db:link xlink:href="http://perldoc.perl.org/functions/chop.html">the built-in
+function chop()</db:link> in order to remove newline characters from the end
+of lines read using the diamond operator (<db:code>&lt;&gt;</db:code>), because this
+may cause the last character in a line without a line feed character to be
+removed. Instead, use <db:link xlink:href="http://perldoc.perl.org/functions/chomp.html">chomp()</db:link>.
+</db:para>
+      <db:para>
+If you expect to process DOS/Windows-like text files whose lines end with the
+dual Carriage Return-Line Feed character on Unix systems then use the
+following in order to trim them: <db:code>$line =~ s/\x0d?\x0a\z//;</db:code>.
+</db:para>
+      <db:para>
+For more information see:
+</db:para>
+      <db:itemizedlist>
+<db:listitem>
+<db:para>
+<db:link xlink:href="http://onlamp.com/pub/a/onlamp/2006/08/17/understanding-newlines.html">"Understanding Newlines"</db:link> - by Xavier Noria on OnLAMP.com.
+</db:para>
+</db:listitem>
+<db:listitem>
+<db:para>
+<db:link xlink:href="http://en.wikipedia.org/wiki/Newline">Wikipedia article about newlines</db:link>
+</db:para>
+</db:listitem>
+</db:itemizedlist>
+    </db:section>
+    <db:section role="item" xml:id="lowercase_modules_and_pkgs">
+      <db:info>
+        <db:title>Don't start Modules and Packages with a Lowercase Letter</db:title>
+      </db:info>
+      <db:para>
+Both modules and packages (the latter also known as namespaces) and all
+intermediate components thereof should always start with an uppercase letter,
+because modules and packages that start with a lowercase letter are
+reserved for pragmas. So this is bad:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+# This is file person.pm
+package person;
+use strict;
+use warnings;
+1;
+</db:programlisting>
+      <db:para>
+And this would be better:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Better code!
+# This is file MyProject/Person.pm
+package MyProject::Person;
+use strict;
+use warnings;
+.
+.
+.
+1;
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="indirect-object-notation">
+      <db:info>
+        <db:title>Avoid Indirect Object Notation</db:title>
+      </db:info>
+      <db:para>
+Don't use the so-called “Indirect-object notation” which can be seen in a lot
+of old code and tutorials and is more prone to errors:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $new_object = new MyClass @params;
+</db:programlisting>
+      <db:para>
+Instead use the <db:code>MyClass-&gt;new(…)</db:code> notation:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my $new_object = MyClass-&gt;new(@params);
+</db:programlisting>
+      <db:para>
+For more information and the motivation for this advice, see chromatic’s article
+<db:link xlink:href="http://modernperlbooks.com/mt/2009/08/the-problems-with-indirect-object-notation.html">“The
+Problems with Indirect Object Notation”</db:link>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="dollar-dollar">
+      <db:info>
+        <db:title>$$myarray_ref[$idx] or $$myhash_ref{$key}</db:title>
+      </db:info>
+      <db:para>
+Don't write <db:code>$$myarray_ref[$idx]</db:code>, which is cluttered and can be easily
+confused with <db:code>(${$myarray_ref})-&gt;[$idx]</db:code>. Instead, use the
+arrow operator - <db:code>$myarray_ref-&gt;[$idx]</db:code>. This also applies for
+hash references - <db:code>$myhash_ref-&gt;{$key}</db:code>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="c-style-for-loops">
+      <db:info>
+        <db:title>C-style for loops</db:title>
+      </db:info>
+      <db:para>
+Some beginners to Perl tend to use C-style-for-loops to loop over an array's
+elements:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+for (my $i=0 ; $i &lt; @array ; $i++)
+{
+    # Do something with $array[$i]
+}
+</db:programlisting>
+      <db:para>
+However, iterating over the array itself would normally be preferable:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+foreach my $elem (@array)
+{
+    # Do something with $elem.
+}
+</db:programlisting>
+      <db:para>
+If you still need the index, do:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+foreach my $idx (0 .. $#array)
+{
+    my $elem = $array[$idx];
+    # Do something with $idx and $elem.
+}
+# perl-5.12.0 and above:
+foreach my $idx (keys(@array))
+{
+    my $elem = $array[$idx];
+    # Do something with $idx and $elem.
+}
+# Also perl-5.12.0 and above.
+while (my ($idx, $elem) = each(@array))
+{
+    # Do something with $idx and $elem.
+}
+</db:programlisting>
+      <db:para>
+An arbitrary C-style for loop can be replaced with a while loop with
+a “continue” block.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="non-intrusive-commenting">
+      <db:info>
+        <db:title>Avoid Intrusive Commenting</db:title>
+      </db:info>
+      <db:para>
+Some commenting is too intrusive and interrupts the flow of reading the code.
+Examples for that are the <db:code>########################</db:code> hard-rules that
+some people put in their code, the comments using multiple
+<db:link xlink:href="http://en.wikipedia.org/wiki/Number_sign">number signs ("#")</db:link>,
+like <db:code>####</db:code>, or excessively long comment block. Please avoid all those.
+</db:para>
+      <db:para>
+Some schools of software engineering argue that if the code's author feels
+that a comment is needed, it usually indicates that the code is not clear
+and should be factored better (like extracting a method or a subroutine with
+a meaningful name.). It probably does not mean that you should avoid writing
+comments altogether, but excessive commenting could prove as a red flag.
+</db:para>
+      <db:para>
+If you're interested in documenting the public interface of your modules and
+command-line programs, refer to <db:link role="perldoc" xlink:href="http://perldoc.perl.org/perlpod.html">perlpod, Perl's Plain Old
+Documentation (POD)</db:link>, which allows one to quickly and easily document
+one's code. POD has
+<db:link xlink:href="http://search.cpan.org/search?query=pod&amp;mode=all">many extensions
+available on CPAN</db:link>, which may prove of use.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="accessing_object_slots_directly">
+      <db:info>
+        <db:title>Accessing Object Slots Directly</db:title>
+      </db:info>
+      <db:para>
+Since <db:link xlink:href="../../topics/object-oriented/">Perl objects</db:link> are simple
+references some programmers are tempted to access them directly:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+$self-&gt;{'name'} = "John";
+print "I am ", $self-&gt;{'age'}, " years old\n";
+# Or even: (Really bad code)
+$self-&gt;[NAME()] = "John";
+</db:programlisting>
+      <db:para>
+However, this is sub-optimal as explained in
+<db:link xlink:href="http://www.shlomifish.org/lecture/Perl/Newbies/lecture5/accessors/">the
+Perl
+for Newbies section about "Accessors"</db:link>, and one should use accessors
+using code like that:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Good code.
+$self-&gt;_name("John");
+print "I am ", $self-&gt;_age(), " years old\n";
+</db:programlisting>
+      <db:para>
+As noted in the link, you can use one of CPAN's many accessor generators to
+generate accessors for you.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="caret_and_dollar_sign_in_regexes">
+      <db:info>
+        <db:title>'^' and '$' in Regular Expressions</db:title>
+      </db:info>
+      <db:para>
+Some people use "^" and "$" in regular expressions to mean
+beginning-of-the-string or end-of-the-string. However, they can mean
+beginning-of-a-line and end-of-a-line respectively using the <db:code>/m</db:code> flag
+which is confusing. It's a good idea to use <db:code>\A</db:code> for start-of-string
+and <db:code>\z</db:code> for end-of-string always, and to specify the <db:code>/m</db:code> flag
+if one needs to use "^" and "$" for start/end of a line.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="magic_numbers">
+      <db:info>
+        <db:title>Magic Numbers</db:title>
+      </db:info>
+      <db:para>
+Your code should not include <db:link xlink:href="http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Unnamed_numerical_constants">unnamed
+numerical constants also known as "magic numbers" or "magic constants"</db:link>.
+For example, there is one in this code to shuffle a deck of cards:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+for my $i (0 .. 51)
+{
+    my $j = $i + int(rand(52-$i));
+    @cards[$i,$j] = @cards[$j,$i];
+}
+</db:programlisting>
+      <db:para>
+This code is bad because the meaning of 52 and 51 is not explained and they
+are arbitrary. A better code would be:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Good code.
+# One of:
+my $deck_size = 52;
+Readonly my $deck_size =&gt; 52;
+for my $i (0 .. $deck_size-1)
+{
+    my $j = $i + int(rand($deck_size-$i));
+    @cards[$i,$j] = @cards[$j,$i];
+}
+</db:programlisting>
+      <db:para>
+(Of course in this case, you may opt to use a shuffle function from CPAN,
+but this is just for the sake of demonstration.).
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="vars_in_quotes">
+      <db:info>
+        <db:title>String Variables Enclosed in Double Quotes</db:title>
+      </db:info>
+      <db:para>
+One can sometimes see people write code like that:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $name = shift(@ARGV);
+print "$name", "\n";
+if ("$name" =~ m{\At}i)
+{
+    print "Your name begins with the letter 't'";
+}
+</db:programlisting>
+      <db:para>
+However, it's not necessary to enclose $name in double quotes (i.e:
+<db:code>"$name"</db:code>) because it's already a string. Using it by itself as
+<db:code>$name</db:code> will do just fine:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Better code.
+my $name = shift(@ARGV);
+print $name, "\n";
+if ($name =~ m{\At}i)
+{
+    print "Your name begins with the letter 't'";
+}
+</db:programlisting>
+      <db:para>
+Also see <db:link xlink:href="../../uses/text-generation/">our page about text
+generation</db:link> for other ways to delimit text.
+</db:para>
+      <db:para>
+Note that sometimes enclosing scalar variables in double-quotes makes sense -
+for example if they are objects with overloaded stringification. But this is
+the exception rather than the rule.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="at-array-for-subscripting">
+      <db:info>
+        <db:title>@array[$idx] for array subscripting</db:title>
+      </db:info>
+      <db:para>
+Some newcomers to Perl 5 would be tempted to write <db:code>@array[$index]</db:code>
+to subscript a single element out of the array <db:code>@array</db:code>. However,
+<db:code>@array[$index]</db:code> is a single-element array <db:emphasis role="bold">slice</db:emphasis>. To get
+a single subscript out of <db:code>@array</db:code> use <db:code>$array[$idx]</db:code> (with
+a dollar sign). Note that if you want to extract several elements, you can
+use an array slice such as <db:code>@array[@indexes]</db:code> or
+<db:code>@array[$x,$y] = @array[$y,$x]</db:code>. However, then it's a list which should
+be used in list context.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="vars-a-and-b">
+      <db:info>
+        <db:title>Variables called $a and $b</db:title>
+      </db:info>
+      <db:para>
+One should not create lexical variables called <db:code>$a</db:code> and <db:code>$b</db:code>
+because there are built-in-variables called that used for
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/sort.html">sorting</db:link> and other uses (such as reduce in
+<db:link role="cpan_module" xlink:href="http://metacpan.org/module/List::Util">List::Util</db:link>), which the lexical variables will interfere
+with:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my ($a, $b) = @ARGV;
+.
+.
+.
+# Won't work now.
+my @array = sort { length($a) &lt;=&gt; length($b) } @other_array;
+</db:programlisting>
+      <db:para>
+Instead, use other single-letter variable names such as
+<db:code>$x</db:code> and <db:code>$y</db:code>, or better yet give more descriptive names.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="flow-stmts-without-labels">
+      <db:info>
+        <db:title>Flow Control Statements Without an Explicit Label</db:title>
+      </db:info>
+      <db:para>
+One can sometimes see flow-control statements such as
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/next.html">next</db:link>, <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/last.html">last</db:link> or
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/redo.html">redo</db:link> used without an explicit label following
+them, in which case they default to re-iterating or breaking out of the
+innermost loop. However, this is inadvisable, because later on, one may modify
+the code to insert a loop in between the innermost loop and the flow control
+statement, which will break the code. So always append a label to "next",
+"last" and "redo" and label your loops accordingly:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+LINES:
+while (my $line = &lt;&gt;)
+{
+    if ($line =~ m{\A#})
+    {
+        next LINES;
+    }
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="abuse_of_array_last_index">
+      <db:info>
+        <db:title>($#array + 1) and Other Abuses of $#.</db:title>
+      </db:info>
+      <db:para>
+The <db:code>$#array</db:code> notation gives the last index in <db:code>@array</db:code> and
+is always equal to the array length minus one. Some people use it to signify
+the length of the array:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my @flags = ((0) x ($#names +1))
+</db:programlisting>
+      <db:para>
+However this is unnecessary because one can better do it by evaluating
+<db:code>@names</db:code> in scalar context, possibly by saying <db:code>scalar(@names)</db:code>.
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Better code.
+my @flags = ((0) x @names);
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="last_elems_of_array">
+      <db:info>
+        <db:title>$array[$#array], $array[$#array-1], etc.</db:title>
+      </db:info>
+      <db:para>
+One can sometimes see people references the last elements of arrays using
+notation such as <db:code>$array[$#array]</db:code>, <db:code>$array[$#array-1]</db:code>
+or even <db:code>$array[scalar(@array)-1]</db:code>. This duplicates the identifier
+and is error prone and there's a better way to do it in Perl using
+negative indexes. <db:code>$array[-1]</db:code> is the last element of the array,
+<db:code>$array[-2]</db:code> is the second-to-last, etc.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="re_string_interpolate">
+      <db:info>
+        <db:title>Interpolating Strings into Regular Expressions</db:title>
+      </db:info>
+      <db:para>
+One can often see people interpolate strings directly into regular expressions:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $username = shift(@ARGV);
+open my $pass_fh, '&lt;', '/etc/passwd'
+    or die "Cannot open /etc/passwd - $!";
+PASSWD:
+while (my $line = &lt;$pass_fh&gt;)
+{
+    if ($line =~ m{\A$username}) \# Bad code here.
+    {
+        print "Your username is in /etc/passwd\n";
+        last PASSWD;
+    }
+}
+close($pass_fh);
+</db:programlisting>
+      <db:para>
+The problem is that when a string is interpolated into a regular expression
+it is interpolated as a mini-regex, and special characters there behave like
+they do in a regular expression. So if I input <db:code>'.*'</db:code> into the command
+line in the program above, it will match all lines. This is a special case
+of <db:link xlink:href="http://community.livejournal.com/shlomif_tech/35301.html">code
+or markup injection</db:link>.
+</db:para>
+      <db:para>
+The solution to this is to use \Q and \E to signify a
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/quotemeta.html">quotemeta()</db:link> portion that will treat the
+interpolated strings as plaintext with all the special characters escaped.
+So the line becomes: <db:code>if ($line =~ m{\A\Q$username\E})</db:code>.
+</db:para>
+      <db:para>
+Alternatively, if you do intend to interpolate a sub-regex, signify this
+fact with a comment. And be careful with regular expressions that are accepted
+from user input.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="overuse_dollar_underscore">
+      <db:info>
+        <db:title>Overusing $_</db:title>
+      </db:info>
+      <db:para>
+It's a good idea not to overuse <db:code>$_</db:code> because using it, especially in
+large scopes, is prone to errors, including many subtle ones. Most Perl
+operations support operating on other variables and you should use lexical
+variables with meaningful names instead of $_ whenever possible.
+</db:para>
+      <db:para>
+Some places where you have to use <db:code>$_</db:code> are <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/map.html">map</db:link>,
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/grep.html">grep</db:link> and other functions like that, but even in
+that case it might be desirable to set a lexical variable to the value of
+<db:code>$_</db:code> right away: <db:code>map { my $line = $_; … } @lines</db:code>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="mixing_tabs_and_spaces">
+      <db:info>
+        <db:title>Mixing Tabs and Spaces</db:title>
+      </db:info>
+      <db:para>
+Some improperly configured text editors may be used to write code that, while
+indented well at a certain tab size looks terrible on other tab sizes, due
+to a mixture of tabs and spaces. So either use tabs for indentation or make
+sure your tab key expands to a constant number of spaces. You may also wish
+to make use of <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Perl-Tidy">Perl-Tidy</db:link> to properly format your
+code.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="qx_for_command_execution">
+      <db:info>
+        <db:title>`…` or qx// for Executing Commands</db:title>
+      </db:info>
+      <db:para>
+Some people are tempted to use backticks (<db:code>`…`</db:code>) or <db:code>qx/…/</db:code>
+for executing commands for their side-effects. E.g:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+use strict;
+use warnings;
+my $temp_file = "tempfile.txt";
+`rm -f $temp_file`;
+</db:programlisting>
+      <db:para>
+However, this is not idiomatic because <db:code>`…`</db:code> and <db:code>qx/…/</db:code> are
+used to trap a command's output and to return it as a big string or as a list
+of lines. It would be a better idea to use
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/system.html">system()</db:link> or to seek more idiomatic Perl-based
+solutions on CPAN or in the Perl core (such as using
+<db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/unlink.html">unlink()</db:link> to delete a file in our case.).
+</db:para>
+      <db:para>
+Some people even go and ask how to make the <db:code>qx/…/</db:code> output go to
+the screen, which is a clear indication that they want to use system().
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="explicit_return">
+      <db:info>
+        <db:title>No Explicit Returns</db:title>
+      </db:info>
+      <db:para>
+As noted in "Perl Best Practices", all functions must have an explicit
+“return” statement, as otherwise they implicitly return the last
+expression, which would be subject to change upon changing the code. If you
+don't want the subroutine to return anything (i.e: it's a so-called
+"procedure"), then write <db:code>return;</db:code> to always return a false value,
+which the caller won't be able to do anything meaningful with.
+</db:para>
+      <db:para>
+Another mistake is to write "return 0;" or "return undef;" to return
+false, because in list context, they will return a one-element list which
+is considered true. So always type <db:code>return;</db:code> to return false.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="varvarname">
+      <db:info>
+        <db:title>"Varvarname" - Using a variable as another variable's name.</db:title>
+      </db:info>
+      <db:para>
+Mark Jason Dominus has written about
+<db:link xlink:href="http://perl.plover.com/varvarname.html">varvarname -
+"Why it's stupid to `use a variable as a variable name'"</db:link>, namely if
+<db:code>$myvar</db:code> is <db:code>'foobar'</db:code> they want to operate on the value of
+<db:code>$foobar</db:code>. While there are ways to achieve similar things in Perl,
+the best way is to use <db:link xlink:href="../../topics/hashes/">hashes</db:link> (possibly
+pointing to complex records with more information) and lookup them by
+the string you want to use. Read the link by Mark Jason Dominus for more
+information.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="leading_underscores">
+      <db:info>
+        <db:title>Use Leading Underscores ('_') for Internal Methods and Functions</db:title>
+      </db:info>
+      <db:para>
+When writing a module use leading underscores in identifiers of methods and
+functions to signify those that are: 1. Subject to change. 2. Are used
+internally by the module. 3. Should not be used from outside. By using
+<db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Pod-Coverage">Pod-Coverage</db:link> one can make sure that the external API
+of the module is documented and it will skip the identifiers with leading
+underscores, that can be thought of as "private" ones.
+</db:para>
+      <db:para>
+Here's an example:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+package Math::SumOfSquares;
+use strict;
+use warnings;
+use List::Utils qw(sum);
+sub _square
+{
+    my $n = shift;
+    return $n * $n;
+}
+sub sum_of_squares
+{
+    my ($numbers) = @_;
+    return sum(map { _square($_) } @$numbers);
+}
+1;
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="print_to_fh">
+      <db:info>
+        <db:title>print $fh @args</db:title>
+      </db:info>
+      <db:para>
+It is preferable to write <db:code>print {$write_fh} @args</db:code>
+over <db:code>print $write_fh @args</db:code> because the latter can more easily be
+mistaken for <db:code>print $write_fh, @args</db:code> (which does something different)
+and does not provide enough visual hints that you are writing to the
+<db:code>$write_fh</db:code> filehandle. Therefore, always wrap the file-handle in
+curly braces (so-called "dative block"). (Inspired by "Perl Best Practices").
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="STDIN_instead_of_ARGV">
+      <db:info>
+        <db:title>Using STDIN instead of ARGV</db:title>
+      </db:info>
+      <db:para>
+One can write code while reading from STDIN:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+use strict;
+use warnings;
+# Strip comments.
+LINES:
+while (my $line = &lt;STDIN&gt;)
+{
+    if ($line =~ m{\A *#})
+    {
+        next LINES;
+    }
+    print $line;
+}
+</db:programlisting>
+      <db:para>
+However, it is usually better to use <db:code>ARGV</db:code> instead of <db:code>STDIN</db:code>
+because it also allows processing the filenames from the command line. This
+can also be achieved by simply saying <db:code>&lt;&gt;</db:code>. So the code becomes:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Better code:
+use strict;
+use warnings;
+# Strip comments.
+LINES:
+while (my $line = &lt;&gt;)
+{
+    if ($line =~ m{\A *#})
+    {
+        next LINES;
+    }
+    print $line;
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="modifying_iterated_array">
+      <db:info>
+        <db:title>Modifying arrays or hashes while iterating through them.</db:title>
+      </db:info>
+      <db:para>
+Some people ask about how to add or remove elements to an existing array or
+hash when iterating over them using “foreach” and other loops. The
+answer to that is that Perl will likely not handle it too well, and it expects
+that during loops the keys of a data structure will remain constant.
+</db:para>
+      <db:para>
+The best way to achieve something similar is to populate a new array or hash
+during the loop by using <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/push.html">push()</db:link> or a hash lookup
+and assignment. So do that instead.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="code_in_foreign_lang">
+      <db:info>
+        <db:title>Comments and Identifiers in a Foreign Language</db:title>
+      </db:info>
+      <db:para>
+Apparently, many non-native English speakers write code with comments and
+even identifiers in their native language. The problem with this is that
+programmers who do not speak that language will have a hard time understanding
+what is going on here, especially after the writers of the foreign language
+code post it in to an Internet forum in order to get help with it.
+</db:para>
+      <db:para>
+Consider what Eric Raymond wrote in
+<db:link xlink:href="http://www.catb.org/~esr/faqs/hacker-howto.html#skills4">his
+"How to Become a Hacker" document</db:link> (where hacker is a software enthusiast
+and not a computer intruder):
+</db:para>
+      <db:blockquote>
+<db:para>
+4. If you don't have functional English, learn it.
+</db:para>
+<db:para>
+As an American and native English-speaker myself, I have previously been
+reluctant to suggest this, lest it be taken as a sort of cultural imperialism.
+But several native speakers of other languages have urged me to point out that
+English is the working language of the hacker culture and the Internet, and
+that you will need to know it to function in the hacker community.
+</db:para>
+<db:para>
+Back around 1991 I learned that many hackers who have English as a second
+language use it in technical discussions even when they share a birth tongue;
+it was reported to me at the time that English has a richer technical
+vocabulary than any other language and is therefore simply a better tool for
+the job. For similar reasons, translations of technical books written in
+English are often unsatisfactory (when they get done at all).
+</db:para>
+<db:para>
+Linus Torvalds, a Finn, comments his code in English (it apparently never
+occurred to him to do otherwise). His fluency in English has been an important
+factor in his ability to recruit a worldwide community of developers for Linux.
+It's an example worth following.
+</db:para>
+<db:para>
+Being a native English-speaker does not guarantee that you have language skills
+good enough to function as a hacker. If your writing is semi-literate,
+ungrammatical, and riddled with misspellings, many hackers (including myself)
+will tend to ignore you. While sloppy writing does not invariably mean sloppy
+thinking, we've generally found the correlation to be strong — and we have no
+use for sloppy thinkers. If you can't yet write competently, learn to.
+</db:para>
+</db:blockquote>
+      <db:para>
+So if you're posting code for public scrutiny, make sure it is written with
+English identifiers and comments.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="perlform">
+      <db:info>
+        <db:title>Using perlform for formatting text.</db:title>
+      </db:info>
+      <db:para>
+One should not use “perlform” for formatting text, because it makes
+use of global identifiers, and should use the
+<db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Perl6-Form">Perl6-Form</db:link> CPAN distribution instead. Also see
+our <db:link xlink:href="../../uses/text-generation/">text generation page</db:link> for
+more information. (Inspired by "Perl Best Practices").
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="obj_new">
+      <db:info>
+        <db:title>Using $obj-&gt;new for object construction.</db:title>
+      </db:info>
+      <db:para>
+Sometimes you can see class constructors such as:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+sub new
+{
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self = {};
+    …
+}
+</db:programlisting>
+      <db:para>
+The problem here is that this allows one to do
+<db:code>$my_object_instance-&gt;new</db:code> to create a new instance of the object,
+but many people will expect it to be invalid or to clone the object. So don't
+do that and instead write your constructors as:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+# Better code:
+sub new
+{
+    my $class = shift;
+    my $self = {};
+    bless $self, $class;
+    …
+}
+</db:programlisting>
+      <db:para>
+Which will disable it and will just allow
+<db:code>ref($my_object_instance)-&gt;new(…)</db:code>. If you need a clone method,
+then code one called "clone()" and don't use "new" for that.
+</db:para>
+      <db:para>
+(Thanks to
+<db:link xlink:href="http://www.stonehenge.com/merlyn/UnixReview/col52.html">Randal L.
+Schwartz's post "Constructing Objects"</db:link> for providing the insight to this).
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="law_of_demeter">
+      <db:info>
+        <db:title>Law of Demeter</db:title>
+      </db:info>
+      <db:para>
+See the <db:link xlink:href="http://en.wikipedia.org/wiki/Law_of_Demeter">Wikipedia article
+about "Law of Demeter" for more information</db:link>. Namely, doing many nested
+method calls like
+<db:code>$self-&gt;get_employee('sophie')-&gt;get_address()-&gt;get_street()</db:code>
+is not advisable, and should be avoided.
+</db:para>
+      <db:para>
+A better option would be to provide methods in the containing objects to
+access those methods of their contained objects. And an even better way would
+be to structure the code so that each object handles its own domain.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="delegating_parameter_passing">
+      <db:info>
+        <db:title>Passing parameters in delegation</db:title>
+      </db:info>
+      <db:para>
+Sometimes we encounter a case where subroutines each pass the same parameter
+to one another in delegation, just because the innermost subroutines in the
+callstack need it.
+</db:para>
+      <db:para>
+To avoid it, create a class, and declare methods that operate on the
+fields of the class, where you can assign the delegated arguments.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="duplicate_code">
+      <db:info>
+        <db:title>Duplicate Code</db:title>
+      </db:info>
+      <db:para>
+As noted in
+<db:link xlink:href="http://www.shlomifish.org/philosophy/books-recommends/#refactoring">Martin
+Fowler's "Refactoring"</db:link> book (but held as a fact for a long time
+beforehand),
+<db:link xlink:href="http://en.wikipedia.org/wiki/Duplicate_code">duplicate code</db:link> is a
+code smell, and should be avoided. The solution is to extract duplicate
+functionality into subroutines, methods and classes.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="long_functions">
+      <db:info>
+        <db:title>Long Functions and Methods</db:title>
+      </db:info>
+      <db:para>
+Another common code smell is
+<db:link xlink:href="http://c2.com/cgi/wiki?LongMethodSmell">long
+subroutines and methods</db:link>. The solution to these is to extract several
+shorter methods out, with meaningful names.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="map_instead_of_foreach">
+      <db:info>
+        <db:title>Using map instead of foreach for side-effects</db:title>
+      </db:info>
+      <db:para>
+You shouldn't be using <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/map.html">map</db:link> to iterate on a list
+instead of foreach if you're not interested in constructing a new list and
+all you are interested in are the side-effects. For example:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+use strict;
+use warnings;
+map { print "Hello $_!\n"; } @ARGV;
+</db:programlisting>
+      <db:para>
+Would be better written as:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+use strict;
+use warnings;
+foreach my $name (@ARGV)
+{
+    print "Hello $name!\n";
+}
+</db:programlisting>
+      <db:para>
+Which better conveys one's intention and may be a bit more efficient.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="ternary_operator_instead_of_if_else">
+      <db:info>
+        <db:title>Using the ternary operator for side-effects instead of if/else</db:title>
+      </db:info>
+      <db:para>
+A similar symptom to the above is people who wish to use the ternary
+inline- conditional operator (<db:code>? :</db:code>) for choosing to execute between
+two different statements with side-effects
+instead of using <db:code>if</db:code> and <db:code>else</db:code>. For example:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+$cond_var ? ($hash{'if_true'} .= "Cond var is true")
+          : ($hash{'if_false'} .= "Cond var is false")
+</db:programlisting>
+      <db:para>
+(This is assuming the ternary operator was indeed written correctly, which
+is not always the case).
+</db:para>
+      <db:para>
+However, the ternary operator is meant to be an expression that is a choice
+between two values and should not be used for its side-effects. To do the
+latter, just use <db:code>if</db:code> and <db:code>else</db:code>:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+if ($cond_var)
+{
+    $hash{'if_true'} .= "Cond var is true";
+}
+else
+{
+    $hash{'if_false'} .= "Cond var is false";
+}
+</db:programlisting>
+      <db:para>
+This is safer, and better conveys one’s intentions.
+</db:para>
+      <db:para>
+For more information, refer to
+<db:link xlink:href="http://www.nntp.perl.org/group/perl.beginners/2012/04/msg120480.html">a
+relevant thread on the Perl beginners mailing list</db:link> (just make sure you read
+it in its entirety).
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="nested_top_level_subroutines">
+      <db:info>
+        <db:title>Nested top-level subroutines</db:title>
+      </db:info>
+      <db:para>
+One should not nest an inner top-level subroutine declared using
+<db:code>sub inner</db:code> inside of an outer one, like so:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+sub outer
+{
+    sub inner
+    {
+        .
+        .
+        .
+    }
+    # Use inner here
+}
+</db:programlisting>
+      <db:para>
+This code will compile and run, but may break in subtle ways.
+</db:para>
+      <db:para>
+The first problem with this approach is that <db:code>inner()</db:code> will still be
+visible outside <db:code>outer()</db:code>, but the more serious problem is that the
+inner subroutine will only get one copy of the lexical variables inside
+<db:code>outer()</db:code>.
+</db:para>
+      <db:para>
+The proper and safer way to declare an inner subroutine is to declare
+a lexical variable and set it to an anonymous subroutine, which is
+also known as a closure:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+sub outer
+{
+    my ($foo, $bar) = @_;
+    my $print_foo = sub {
+        print "Foo is '$foo'\n";
+        return;
+    };
+    $print_foo-&gt;();
+    $foo++;
+    $print_foo-&gt;();
+    return;
+}
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="grep_instead_of_any">
+      <db:info>
+        <db:title>Using grep instead of any and friends</db:title>
+      </db:info>
+      <db:para>
+Sometimes one can see people using <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/grep.html">grep</db:link> to find
+the first matching element in an array, or whether such an element exists at
+all. However, grep is intended to extract <db:emphasis role="bold">all</db:emphasis> matching elements out
+of a list, not just the first one, and as a result will not stop until it
+finds them all. To remedy this look at either <db:code>first()</db:code> from
+<db:link role="cpan_module" xlink:href="http://metacpan.org/module/List::Util">List::Util</db:link> (to find the first match) or
+"any/all/notall/none" from <db:link role="cpan_module" xlink:href="http://metacpan.org/module/List::MoreUtils">List::MoreUtils</db:link> (to find
+whether a single element exists). These better convey one's intention
+and may be more efficient because they stop on the first match.
+</db:para>
+      <db:para>
+One should note that if one does such lookups often, then they should try
+to use a <db:link xlink:href="../../topics/hashes/">hash</db:link> instead.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="FileHandle_module">
+      <db:info>
+        <db:title>Using the FileHandle Module</db:title>
+      </db:info>
+      <db:para>
+The FileHandle module is old and bad, and should not be used. One should
+use the <db:link xlink:href="http://perldoc.perl.org/IO/Handle.html">IO::Handle</db:link>
+family of modules instead.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="file_includes">
+      <db:info>
+        <db:title>"Including" files instead of using Modules</db:title>
+      </db:info>
+      <db:para>
+We are often asked how one can "include" a file in a Perl program (similar
+to <db:link xlink:href="http://php.net/manual/en/function.include.php">PHP's include</db:link>
+or <db:link xlink:href="http://ss64.com/bash/period.html">the shell's
+"source" or "." operators</db:link>. The answer is that the better way is to extract
+the common functionality from all the programs into
+<db:link xlink:href="../../topics/modules-and-packages/">modules</db:link> and load them by
+using "use" or "require".
+</db:para>
+      <db:para>
+Note that <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/do.html">do</db:link> can be used to evaluate a file (but in
+a different scope), but it's almost always not needed.
+</db:para>
+      <db:para>
+Some people are looking to supply a common configuration to their programs
+as global variables in the included files, and those people should look at
+CPAN configuration modules such as <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Config-IniFiles">Config-IniFiles</db:link>
+or <db:link xlink:href="http://search.cpan.org/search?query=json&amp;mode=all">the
+various JSON modules</db:link> for the ability to read configuration files
+in a safer and better way.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="global_vars_iface">
+      <db:info>
+        <db:title>Using Global Variables as an Interface to the Module</db:title>
+      </db:info>
+      <db:para>
+While it is possible to a large extent, one should generally not use global
+variables as an interface to a module, and should prefer having a procedural
+or an object oriented interface instead. For information about this see our
+<db:link xlink:href="../../topics/modules-and-packages/">page about modules and
+packages</db:link> and our <db:link xlink:href="../../topics/object-oriented/">our page
+about object oriented programming in Perl</db:link>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="declaring_all_vars_at_top">
+      <db:info>
+        <db:title>Declaring all variables at the top</db:title>
+      </db:info>
+      <db:para>
+Some inexperienced Perl programmers, possibly by influence from languages
+such as C, like to declare all variables used by the program at the top of
+the program or the relevant subroutines. Like so:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $first_name;
+my $last_name;
+my $address;
+my @people;
+my %cities;
+.
+.
+.
+</db:programlisting>
+      <db:para>
+However, this is bad form in Perl, and the preferable way is to declare all
+the variables when they are first used, and at the innermost scope where they
+should retain their value. This will allow to keep track of them better.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="switch_pm">
+      <db:info>
+        <db:title>Using Switch.pm</db:title>
+      </db:info>
+      <db:para>
+One should not use Switch.pm to implement a
+<db:link xlink:href="http://en.wikipedia.org/wiki/Switch_statement">switch statement</db:link>
+because it's a source filter, tends to break a lot of code, and causes
+unexpected problems. Instead one should either use <db:code>given/when</db:code>, which
+are only available in perl-5.10 and above, or dispatch tables, or alternatively
+plain <db:code>if/elsif/else</db:code> structures.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="threads">
+      <db:info>
+        <db:title>Using threads in Perl</db:title>
+      </db:info>
+      <db:para>
+Some beginners, when thinking they need to multitask their programs start
+thinking they should use perl threads. However, as mentioned in
+<db:link role="perldoc" xlink:href="http://perldoc.perl.org/perlthrtut.html">perlthrtut</db:link>, perl threads are very much unlike
+the traditional thread modules, share nothing by default and are in fact
+heavyweight processes (instead of the usual lightweight ones). See also
+<db:link xlink:href="http://www.perlmonks.org/index.pl?node_id=288022">Elizabeth
+Mattijsen’s write-up about perl's ithreads on perlmonks</db:link>.
+</db:para>
+      <db:para>
+To sum up, usually threads are the wrong answer and you should be using
+forking processes or something like POE (see our
+<db:link xlink:href="../../uses/multitasking/">page about multitasking</db:link>) instead.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="calling-the-shell-too-much">
+      <db:info>
+        <db:title>Calling Shell Commands Too Much</db:title>
+      </db:info>
+      <db:para>
+Some people are tempted to use shell commands for performing
+various tasks using <db:code>`…`</db:code>, <db:code>qx/…/</db:code>, <db:code>system()</db:code>,
+piped-open, etc. However, usually Perl has built-in routines or alternatively
+CPAN modules, which are more portable, and often would be faster than
+calling the shell for help, and they should be used instead.
+</db:para>
+      <db:para>
+As an extreme example, the site <db:emphasis>The Daily WTF</db:emphasis>
+had <db:link xlink:href="http://thedailywtf.com/Articles/The_UNIX_Philosophy.aspx">a
+feature</db:link> which featured the following code to determine the file size
+in Perl:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $filesize = `wc -c $file | cut -c0-8 | sed 's/ //g'`;
+</db:programlisting>
+      <db:para>
+Reportedly, replacing this line with <db:code>my $filesize = -s $file</db:code> (which
+as noted earlier should have been called <db:code>$filename</db:code> instead), resulted
+in the program being 75 minutes faster on average (!).
+</db:para>
+      <db:para>
+Normally, if you find yourself using UNIX text processing commands such as
+“sed”, “awk”, “grep”, and “cut”, you should
+implement it in pure-Perl code.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="missing-semicolons-at-the-end-of-blocks">
+      <db:info>
+        <db:title>Missing Semicolons at the end of blocks</db:title>
+      </db:info>
+      <db:para>
+The perl interpreter allows one to omit the last trailing semicolon (";") in
+the containing block. Like so:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+if ( COND() )
+{
+     print "Success!\n";
+     call_routine() \# No semicolon here.
+}
+</db:programlisting>
+      <db:para>
+However, this isn't a good idea, because it is inconsistent, and may cause
+errors (or obscure failures) if one-or-more statements are added afterwards.
+</db:para>
+      <db:para>
+As a result, you should end every statement with a semicolon (";") even i
+it’s the last one. A possible exception to this may be single-line and/or
+single-statement blocks like in <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/map.html">map</db:link>.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="list-form-of-open-with-one-arg">
+      <db:info>
+        <db:title>List form of open with one argument.</db:title>
+      </db:info>
+      <db:para>
+Recent versions of of perl introduced the list-forms of piping to and from a
+command, such as <db:code>open my $fh, '-|', 'fortune', $collection</db:code> or
+<db:code>open my $printer, '|-', 'lpr', '-Plp1'</db:code>. However, not only they are
+not implemented on Windows and other UNIX-like systems yet, but when one passes
+only one argument to them, they pass it to the shell verbatim.
+</db:para>
+      <db:para>
+As a result, if one passes an array variable to them, as in:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+open my $fh, '-|', @foo
+    or die "Could not open program! - $!"
+</db:programlisting>
+      <db:para>
+One can pass only a single argument to <db:code>@foo</db:code>, which would be dangerous.
+To mitigate that, one should use the <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/IPC-Run">IPC-Run</db:link>
+or the <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/IPC-System-Simple">IPC-System-Simple</db:link> CPAN distributions.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="trailing-whitespace">
+      <db:info>
+        <db:title>Trailing Whitespace</db:title>
+      </db:info>
+      <db:para>
+With many editors, it can be common to write new code or modify existing
+one, so that some lines will contain trailing whitespace, such as
+spaces (ASCII 32 or 0x20) or tabs characters. These trailing spaces normally
+do not cause much harm, but they are not needed and can be distracted.
+</db:para>
+      <db:para>
+While you should not feel bad about having trailing space, it is a good idea
+to sometimes search for them using a command such as <db:code>ack '[ \t]+$'</db:code>
+(or <db:code>ack -a '[ \t]+$'</db:code> for completeness - see
+<db:link xlink:href="http://betterthangrep.com/">ack</db:link>, and get rid of them.
+</db:para>
+      <db:para>
+Some editors also allow you to highlight trailing whitespace when present. See
+for example:
+</db:para>
+      <db:itemizedlist>
+<db:listitem>
+<db:para>
+<db:link xlink:href="http://vim.wikia.com/wiki/Highlight_unwanted_spaces">Highlight
+unwanted spaces in Vim</db:link>. Also see <db:link xlink:href="http://vim.wikia.com/wiki/Highlight_unwanted_spaces">this post</db:link>.
+</db:para>
+</db:listitem>
+<db:listitem>
+<db:para>
+<db:link xlink:href="http://emacswiki.org/emacs/ShowWhiteSpace">EmacsWiki:
+Show White Space</db:link>.
+</db:para>
+</db:listitem>
+</db:itemizedlist>
+    </db:section>
+    <db:section role="item" xml:id="string-eval">
+      <db:info>
+        <db:title>Misusing String Eval</db:title>
+      </db:info>
+      <db:para>
+String <db:link role="perldoc_func" xlink:href="http://perldoc.perl.org/functions/eval.html">eval</db:link> allows one to compile and execute
+(possibly generated) strings as Perl expressions. While it is a powerful
+feature, there are usually better and safer ways to achieve what you want
+using string <db:code>eval ""</db:code>. So you should only use it, if you are an expert
+and really know what you are doing.
+</db:para>
+      <db:para>
+Related to string eval, is using two or more <db:code>/e</db:code> flags in the
+<db:code>s///</db:code> substitution. While one /e flag is often useful (for example
+when substituting counters like in <db:code>s/#\./($i++)."."/ge</db:code>) the second
+/e flags just evaluates the generated expression again. This can easily be done
+with using string eval inside the right-hand-side, assuming it is needed which
+is normally not the case.
+</db:para>
+    </db:section>
+    <db:section role="item" xml:id="dash-starting-named-params">
+      <db:info>
+        <db:title>Named Parameters That Start With Dash</db:title>
+      </db:info>
+      <db:para>
+If you're defining interfaces that accept a flattened hash or a hash reference
+of named parameters, there is no need to call the parameters with keys starting
+with a dash, like so:
+</db:para>
+      <db:programlisting xml:space="preserve" role="bad_code" language="perl"># Bad code
+
+
+my $obj = MyClass-&gt;new(
+    {
+        -name =&gt; "George",
+        -occupation =&gt; "carpenter",
+        -city =&gt; "Inverness",
+    }
+);
+</db:programlisting>
+      <db:para>
+The dashes are not needed because Perl can safely escape and deal with plain
+names that only contain alphanumeric characters and underscores, and they
+just add clutter to the code. Named arguments starting with dashes were
+prevalent in some early modules such as <db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Tk">Tk</db:link> or
+<db:link role="cpan_dist" xlink:href="http://metacpan.org/release/Config-IniFiles">Config-IniFiles</db:link>, but they should not be used in
+more modern modules.
+</db:para>
+      <db:para>
+Instead, design your interfaces with calling conventions like so:
+</db:para>
+      <db:programlisting xml:space="preserve" language="perl">
+my $obj = MyClass-&gt;new(
+    {
+        name =&gt; "George",
+        occupation =&gt; "carpenter",
+        city =&gt; "Inverness",
+    }
+);
+</db:programlisting>
+    </db:section>
+    <db:section role="item" xml:id="code_and_markup_injection">
+      <db:info>
+        <db:title>Code and Markup Injection</db:title>
+      </db:info>
+      <db:para>
+Care must be taken when constructing statements that are passed to an
+interpreter, when putting arbitrary strings inside (using string interpolation
+or other methods). This is because if the strings are subject to input from
+the outside world (including the users), then one can use specially crafted