Let perl tell you how to code

I had to work on Perl 5.005 today. It’s not my favorite version of Perl, but sometimes (well, most times), I don’t get to pick the version that a customer has to use. I just suck it up and drive on. Usually I have a bit of a re-education period where I have to remember which features showed up or disappeared, and which warnings were actually present. For instance, you may remember that putting an email address in a double-quoted string was a fatal error:

$email = "[email protected]";

Since Perl thinks that I want to interpolate @example but there there is no array with that name, it freaks out:

% perl5.005_04 script.pl
In string, @example now must be written as \@example at script.pl line 1, near "[email protected]"
Execution of script.pl aborted due to compilation errors.

What I forgot, however, is how, even before Perl Best Practices, perl tried to encourage you to code in a certain style. The Perl documentation has had style suggestions in perlstyle for a long time, but those are mostly the higher-level, more fluffy sorts of style suggestions. The older perls went much further at lower levels. Consider this code that fixes the compilation error:

my $email = "buster\@example.com";

Fortunately, the code compiles. It issues several warnings though:

% perl5.005_04 script.pl
Use of my confuses people and limits the visibility of your variable, at script.pl line 1
Scalar name email is a dictionary word, at script.pl line 1
Scalar name email has more than three characters, at script.pl line 1
Vowels in variable name, at script.pl line 1
All-lowercased variable name, script.pl line 1
Extra whitespace around operator =, at script.pl line 1
Missing use of special punctuation variables, at script.pl line 1

Or, this code:

@SqR=map { $_ ** 2 } 1 .. 10;

Some of the same warnings show up, but some are new. I’m not sure why this code triggers the “too recent” warning but the other one doesn’t (Update: it was a bug in the warnings because using map triggered the Perl 3 warning mode):

% perl5.005_04 script.pl
Use of built-in without parentheses, at script.pl line 1
Scalar name sqrs has more than three characters, at script.pl line 1
Use of map. Why do you hate foreach so much? at script.pl line 1
Use of .., which might make people read the documentation, at script.pl line 1
Extra whitespace around operator **, at script.pl line 1
Operator ** missing in C, at script.pl line 1
Extra whitespace around operator .., at script.pl line 1
Perl version 5.005_04 is too recent, at script.pl line 1
Possible use of data structure instead of scalars, at script.pl line 1

Many people don’t realize that they can turn on perl diagnostics to get fuller explanations when they don’t understand the warnings:

% perl5.005_04 -Mdiagnostics script.pl
(W) Scalar name sqrs has more than three characters, at script.pl line 1

Your variable name used more characters than you needed. You only need to 
use enough characters to make the variable name unique, so perl warns you
about the extra typing. Additionally, longer variable names take longer 
for other programmers to read and distract them, they take more toner to
print, and they disable obfuscation mode.

(W) Use of .., which might make people read the documentation, at script.pl line 1

No one really knows what .. does or where they'd find the documentation. Try
to find a simpler way to do whatever .. does. Have you considered just typing
in all the values as an array? That way, you can see all the values and know
what they are.

(W) Use of built-in without parentheses, at script.pl line 1

Use parentheses to have more characters in your source. This helps other
programmers know what is going on, and it makes it look like you did more
work if your boss ever wants to ((see)( )(your)( )(code)(.))(( ))((It's)( )(also)( )(easier)( )((to)( )(see)( )(how)( )(things)( )(group))(.)).
With parentheses, perl can store your source in less space.

It took me about an hour to remember to use the style appropriate for the older perls. But, even before things such as Perl::Critic, Perl has always been very good at encouraging programmers to code in a certain way. So, by following perl’s suggestions, I finally get the right code that is warning free:

for(((1),(2),(3),(4),(5),(6),(7),(8),(9),(10))){push((@SqR),($_*$_))}

December 7, 2010. chromatic encouraged me to update the example for Modern Perl. Styles evolve and this code looks much different with current best practices. Now Perl can handle Unicode. The other big change is the use of foreach instead of for, which I think is silly but it’s what most people like. Note the order of loading some modules is important:

use Modern::Perl;use Moderner::Perl;use PostModern::Perl;use strictures;
use Moose;use Catalyst;
use English qw(-no_match_vars -no_monkey_shines);use namespace::autoclean;
use utf8;use charnames;foreach(split//,"\N{DIGIT ONE}\N{DIGIT TWO}\N{DIGIT THREE}\N{DIGIT FOUR}\N{DIGIT FIVE}\N{DIGIT SIX}\N{DIGIT SEVEN}\N{DIGIT EIGHT}\N{DIGIT NINE}\N{DIGIT ONE}\N{DIGIT ZERO}",10){push(($S_q_R),($DEFAULT_UNDERSCORE_NAME_HARDER_TO_REMEMBER_THAN_*$DEFAULT_UNDERSCORE_NAME_HARDER_TO_REMEMBER_THAN_))}
Leave a comment

0 Comments.

Leave a Reply

You must be logged in to post a comment.