Don’t look at that CPAN module!

Can’t use CPAN modules? If you can’t, you have company, whether you want it or not. CPAN Dependency Hell is a real problem, and it’s much worse if you’re an experienced Perl programmer. Management might want to clamp down on third-party, unsupported code. Lawyers might be afraid. I don’t want to get into that bit though. I’ll concede, for the purposes of this post, that these people can’t use any CPAN module.

So, they have to do something that a widely-used and widely-recommended CPAN module already does. For instance, they want to parse comma separate values, or they want to extract some text from HTML. They know they can’t use CPAN modules, so they don’t bother looking at CPAN. But, they don’t know how to do it themselves. They think about it for seven minutes. They don’t figure it out. What’s next?

Naturally, they go to Perlmonks or Stackoverflow and ask if there’s an easy way to do the same thing that the module does. That makes you a lazy Defective unworthy of their job. Instead, they are Help Vampires who shift their paid time to your unpaid time.

Some examples, just from Stackoverflow:

Their reasons vary. Some people think everything has to live in one file, even if they are using core modules. That’s fine. Copy the source out of the CPAN module into a single file. It’s actually not that hard to install every pure Perl thing that they want to use, concatenate all of the Perl module files you use, and include that in your program. They can fake %INC to think that the modules are already loaded. That’s not even counting things like PAR or Carton.

That would require some Perl knowledge, though, and some people avoid that when they can. They want the next problem to be just as hard, if not harder, than the current one. If they don’t want to copy the source, they can at least read it. If they can’t use the module, they can look at how the experts have done it and do the same thing. But, that requires the ability to read code, and maybe do something that doesn’t involve typing.

Just because they can’t use that source doesn’t mean they can’t mine it for ideas. However, there’s this fantastical thinking that there is some quick hack that will do the same thing. Surely every module is over-engineered (some are, truly), overly-cautious, and even too correct. All that code in those modules doesn’t do anything. Perl can do anything in one statement, can’t it? Why do these module authors work so hard and write so many tests?

It’s much better to ask people who don’t do it correctly (module or not) to guess at a solution. So, they ask, and then they wait for the unsatisfactory answers to come in. There are the tired experts and experienced practitioners worn out by these questions, who just tell them to use the modules. There are the newbies who guess at solutions that cover only the 3% of the problem they’ve ever encountered. Half of those think that input data never change, so their special case guesses are rock solid. They’re content to punt the problem to the next person, using the IWBHWIB (“I won’t be here when it breaks”). They’ve already got their next job, with adequate references, before anyone notices.

There’s another sort of defective programmer, the NIH variety, and I don’t mean those who work at the National Institute of Health. These are the “not invented here” types. Sometimes these Defectives just can’t accept that anyone is smarter than them. They get wrapped up in the ego competition or some notion of purity. Everything has to work just so. But, it’s never the best code that wins: it’s the good enough code that gets the job done at the right time. With appropriate use of interfaces, they could use CPAN modules at first and replace them when they have time.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Missing the big picture

chromatic is a bit harsh on Seda Özses’s article “Very simple login using Perl, jQuery, Ajax, JSON and MySQL” on IBM developerWorks, and his tone encouraged a lot of other people to be equally harsh. This has always been one of the biggest problems for technical communities: they forget that a person is on the other side. Not only that, they forget that a person is also on their side. I think chromatic could have modulated his tone and formed a very useful post had he actually explained his changes in the code.

Now, to be fair, the original article, which I did not see, was worse than the current one according to the gossip. And, I mean gossip. What is this? Middle school? I saw that Dave Cross tweeted about the bad article, then whoever controls The Perl Foundation twitter account retweeted it with five other people. If anyone wrote to Seda first with a patch, please speak up, but if your tweet isn’t “I wrote to so and so with a patch and they told me to get stuffed”, Twitter isn’t always the best route. Sure, Kevin Smith may have Southwest sucking up to him now, but if you followed the whole story, it was only for him.

chromatic gracefully slides over the fact that Seda actually updated the article because that belies his intent of public shaming. He’s still on the attack because no bad code can be allowed to live. And, to be fair to chromatic, he says “It’s okay to write baby Perl, but it’s baffingly irresponsible to publish said baby Perl as an example from which you expect other novices to learn.” I say “It’s lame to tell someone their fly is down by screaming it to the entire room”.

Here’s the code that Seda Özses presented when chromatic started his post (and is not the original or current code in the article):

#!/usr/bin/perl
use CGI qw(:all);
use DBI;
use DBD::mysql;

# read the CGI params
$CGI = new CGI();
$username = $CGI->param("username");
$password = $CGI->param("password");

# connect to the database
$DBH = DBI->connect("DBI:mysql:database=mydb;host=localhost;port=2009",
	"mydbusername", "mydbpassword")
	or die($DBI::errstr);

# check the username and password in the database
$query = qq{SELECT id FROM users WHERE username=? && password=?};
$query = $DBH->prepare($query);
$query->execute($username,$password);
$ref = $query->fetchrow_hashref() || 0;
$userID = $ref->{"id"};

# create a JSON string according to the database result
$JSON = ($userID) ?
	qq{{"success" : "login is successful", "userid" : "$userID"}} 	:
	qq{{"error" : "username or password is wrong"}};

# return JSON string
print qq{Content-type: application/json; charset=utf8\n\n};
print $JSON;

What’s chromatic’s beef here? He doesn’t say because he falls into the trap that many über-coders do: they think that code speaks for itself. It doesn’t, which is why I contend that so many people can’t read your code. chromatic doesn’t care as much about teaching anyone to do better as making his point, so he becomes the guy that makes you think all Perlers are assholes.

I’ll explain some of it though:

  • Seda doesn’t use strict or warnings. These are handy development aids to keep you on track. I don’t use warnings in production code either, though, since I can easily turn them on while I develop. Debate among yourself on that one, though.
  • Seda imports :all from CGI.pm, but doesn’t use anything that she imported. So, there’s a little cut-n-paste cargo-culting there. It’s not that big of a deal though.
  • Seda loads the DBD::mysql, although DBI will do that for her. You only need to load the modules you directly use. You don’t have to directly load the modules that other modules use.
  • Seda doesn’t validate the user input.
  • $ref might not be a reference, so the $ref->{"id"} might blow up.
  • Seda doesn’t use taint-checking, a knee-jerk prophylactic that’s a favorite among people who just want to be snide.
  • Seda uses the indirect object form, new CGI. This was the documented style up through CGI 3.45, released in August 2009. Perl 5.10.1 came with CGI 3.43. That documented style didn’t change until Perl 5.12.0 included CGI 3.48.
  • chromatic asserts that you can’t make a simple CGI response without using the CGI.pm module.
  • chromatic doesn’t like the style.

And here’s chromatic’s code, which I think is equally bad:

#!/usr/bin/perl -T

use strict;
use warnings;

use CGI;
use DBI;

my $q        = CGI->new;
my $username = $q->param("username");
my $password = $q->param("password");

my $dbh = DBI->connect(
	'DBI:mysql:database=mydb;host=localhost;port=2009',
	'mydbusername', 'mydbpassword'
) or die $DBI::errstr;

my $sth = $dbh->prepare(
	'SELECT id FROM users WHERE username=? and password=?;'
);
$sth->execute($username, $password);

my $json;

if (my ($id) = $sth->fetchrow_array)
{
	$json = qq|{"success" : "login is successful", "userid" : "$id"}|;
}
else
{
	$json = qq|{"error" : "username or password is wrong"}|;
}

print $q->header(
	-type    => 'application/json',
	-charset =>  'utf-8',
), $json;

So what’s wrong with chromatic’s code? First, because of his position, he’s set himself up as a bigger target. He can’t complain about someone else’s code then make a bunch of mistakes himself.

  • chromatic has turned on taint-checking, but then does nothing with it. He doesn’t scrub the PATH environment variable, untaint the CGI input, or use the taint features of DBI. He doesn’t do most of the stuff I go through in my security chapter of Mastering Perl.
  • chromatic still uses CGI.pm. People do that because it’s in the Standard Library. It’s an ugly, monolithic waste of cycles and memory in this case though. Something like CGI::Simple would do the job nicely without the bloat.
  • While we’re both being pedantic, chromatic leaves hard-coded configuration inside the script. He should get the username, password, and non-standard port from non-code sources, such as a configuration file.
  • Instead of returning a valid response on a failure to connect to the database, chromatic just die‘s. The user will just see some sort of “500 Internal Server Error” page. Really? In 2011, from the author of Modern Perl?
  • chromatic uses the DBI error in his die message, potentially exposing infrastructure details that an attacker might use later. The user doesn’t need to know that level of error. And, DBI already has the RaiseError feature to do this. You want the error message to go into the log file and not make it out to the user. Where is that STDERR really going?
  • chromatic turns on strict and warnings. Although that adds no value to this code, if someone develops it further, those pragmas can help can help.
  • chromatic loads only the modules he directly uses, and doesn’t import anything.
  • chromatic violates the DRY principle. How many times does he have to type $json to assign to it once? Seda’s version was better, even though she needed to improve her conditional. I would have used do, myself.
  • chromatic insists that she use the CGI.pm module to make a CGI response, but he lets himself make a JSON data structure by hand. What’s in $id? chromatic didn’t encode that for JSON, so he can output an invalid object there. Hard-coding message formats is also quite a bad practice, but chromatic lets that slide too. Wrap that in an interface that all of your applications can use.

Again, to be fair, chromatic says in a comment “I wanted to make the minimal responsible changes to the program to improve its modernity. I also prefer to have connection information outside of my programs, but that’s also a larger change.” I don’t think he accomplished that, but he doesn’t let himself because he focuses on the least useful parts of the whole mess.

But, there’s no real improvement here. It’s the same code with the same problems, structurally. chromatic’s real beef is that someone without a lot of Perl experience used baby Perl in an article. That is, unless you are an expert, you shouldn’t be writing about Perl, at least in his mind. There’s no place for compassion or humanity: you either get it exactly right the first time, or he will publicly shame you, although passive-aggressively because he won’t use your name (it doesn’t matter because you aren’t a real person anyway).

It’s amazingly difficult to present useful code in a tutorial, and chromatic knows that. It’s a side issue to him though. If the Perl authors all wrote complete and correct programs, with good style, good error checking and handling, proper configuration, proper logging, and everything else a robust program needs, no matter the language, we wouldn’t be able to illustrate the concept that we want to point out.

I’m not defending the code that Seda posts, but I understand the situation. chromatic understands it to. An author’s job is to show enough to illustrate the point without causing unnecessary distractions. The reader’s job, at least in the mind of authors, is to learn the key points and integrate that with other knowledge. Tutorials don’t present production-ready programs just for that reason. Authors expect (and respect) that their readers aren’t idiots, even if most of them are. Would you read any article that went through every special and edge case just to show you how to output some JSON?

And, to be honest, if I were starting out in Perl today and ran into people like chromatic, I probably would find some other language to use. I wrote a lot of dumb Perl. It showed up in The Perl Journal and at The Perl Conference. I still remember Tom Phoenix coming up to me, when I knew no one else in the community, and saying “That’s really neat, but what if you did this”. I met a lot of welcoming and nice people, and I decided I want to keep meeting them so I convinced a lot of people to form NY.pm, then Perl Mongers.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

It’s precedence, not context

Ovid blames Perl for a newbie-level mistake in a Twitter post.
Marcel goes on to misread the problem as one of context. Ovid posts a fix that uses parentheses to solve the precedence problem. This is chiefly a problem of code reading skills.

Here’s the code:

$ perl -MData::Dumper -e 'sub boo { 1,2,3 } my @x = (boo()||5,8,7); print Dumper \@x'

The output is:

$VAR1 = [
          3,
          8,
          7
        ];

Ovid doesn’t say much about what he thinks should happen, but it shouldn’t be hard for any person who actually knows Perl (and programming), to figure it out. If you understand precedence, you know which order things will occur.

First, you have to break it down into what happens when. Many experienced people often skip this step because they think their experience should allow them to skip the basics. They try to take in complex expressions all at once and figure out what they do. That’s where people get confused. They ignore the few simple rules of code reading.

Perl figures out the right side of the assignment operator first, so you have to figure out this expression, which is in list context because of the assignment to @x, an array:

(boo()||5,8,7)

In list context, the comma operator separates the elements of the list. There are only a few operators lower in precedence, and || isn’t one of them. The list is then going to be the results of these three expressions:

boo()||5
8
7

This is not what some people (maybe Ovid) don’t expect because they parse it as the choice between two lists:

boo()
(5,8,7)

Most of the misunderstanding comes from thinking the comma is just a way to separate items instead of thinking about it as an operator that has precedence like other operators. Some of the rest of the misunderstanding comes from perceptual narrowing; people are primed to think about lists so they forget what they should know and substitute new rules that only deals with lists.

Change the comma to a different, unfamiliar character, such as ‡, and show it to a programmer who understands precedence and I assert the confusion disappears because the programmer doesn’t insert his misconceptions about the comma into reading the code:

bar() || 5 ‡ 8 ‡ 7

Once you understand the precedence, the last two expressions of the list, 8 and 7, are easy. The first one is easy too. If you looked at it by itself you shouldn’t have a problem with it. You call boo() in scalar context because || is a scalar argument. If it returns a true value, use it. Otherwise, use 5. That’s easy enough too. You might recognize the process better if you saw it with a different scalar operator, such as +:

bar() + 5

The definition for the subroutine is just boo { 1,2,3 }. In scalar context, that is the final element in the series because that’s what the comma operator in scalar context does. Two things are lacking here in most people’s analysis: the comma is an operator and it responds to context. This is almost excusable as a gotcha, but it’s such a well known gotcha that a practicing Perl programmer should know it. This isn’t some obscure corner of the language. It’s the very basics of how the language works.

The perlop documentation is quite clear. The comma operator in scalar context evaluates its left expression and discards it (so, there may be side effects), then evaluates its rightmost element, in this case three, and returns it. There’s even an example in the perlfaq4′s “What’s the difference between a list and an array” that tells you exactly that, and it does that because so many people make this same mistake.

Experienced programmers often charge ahead where they’d do well to read the documentation. It doesn’t matter what you think it should do; it only matters what it does. Intuition is fine when it works out, but it’s not an excuse for a lack of knowledge or education. Intuition is a fool’s game; it only has hope when everyone thinks the same, and nobody does.

The basics matter quite a bit. Don’t get lazy.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Don’t blame your misunderstanding of precedence

Ovid blames Perl for a newbie-level mistake in a Twitter post.
Marcel goes on to misread the problem as one of context. Ovid posts a fix that uses parentheses to solve the precedence problem.

This is chiefly a problem of code reading skills. Here’s the code:

$ perl -MData::Dumper -e 'sub boo { 1,2,3 } my @x = (boo()||5,8,7); print Dumper \@x'

The output is:

$VAR1 = [
          3,
          8,
          7
        ];

Ovid doesn’t say much about what he thinks should happen, but it shouldn’t be hard for any person who actually knows Perl (and programming), to figure it out. If you understand precedence, you know which order things will occur.

First, you have to break it down into what happens when. Many experienced people often skip this step because they think their experience should allow them to skip the basics. They try to take in complex expressions all at once and figure out what they do. That’s where people get confused. They ignore the few simple rules of code reading.

Perl figures out the right side of the assignment operator first, so you have to figure out this expression, which is in list context because of the assignment to @x, an array:

(boo()||5,8,7)

In list context, the comma operator separates the elements of the list. There are only a few operators lower in precedence, and || isn’t one of them. The list is then going to be the results of these three expressions:

boo()||5
8
7

This is not what some people (maybe Ovid) did not expect because they parsed it as the choice between two lists:

boo()
(5,8,7)

Most of the misunderstanding comes from thinking the comma is just a way to separate items instead of thinking about it as an operator that has precedence like other operators. Change the comma to a different, unfamiliar character, such as ‡, and show it to a programmer who understands precedence and I assert the confusion disappears because the programmer doesn’t insert his misconceptions about the comma into reading the code:

bar() || 5 ‡ 8 ‡ 7

Once you understand the precedence, the last two expressions of the list, 8 and 7, are easy. The first one is easy too. If you looked at it by itself you shouldn’t have a problem with it. You call boo() in scalar context because || is a scalar argument. If it returns a true value, use it. Otherwise, use 5. That’s easy enough too. You might recognize the process better if you saw it with a different scalar operator, such as +:

bar() + 5

The definition for the subroutine is just boo { 1,2,3 }. In scalar context, that is the final element in the series because that’s what the comma operator in scalar context does. Two things are lacking here in most people’s analysis: the comma is an operator and it responds to context. This is almost excusable as a gotcha, but it’s such a well known gotcha that a practicing Perl programmer should know it. This isn’t some obscure corner of the language. It’s the very basics of how the language works.

The perlop documentation is quite clear. The comma operator in scalar context evaluates its left expression and discards it (so, there may be side effects), then evaluates its rightmost element, in this case three, and returns it. There’s even an example in the perlfaq4′s “What’s the difference between a list and an array” that tells you exactly that, and it does that because so many people make this same mistake.

Experienced programmers often charge ahead where they’d do well to read the documentation. It doesn’t matter what you think it should do; it only matters what it does. Intuition is fine when it works out, but it’s not an excuse for a lack of knowledge or education. Intuition is a fool’s game; it only has hope when everyone thinks the same, and nobody does.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Practically Extinct Rubbish Language

Carter Shanklin tweets Maintaining a script I wrote in PERL (aka Practically Extinct Rubbish Language). Not fun.

It might be more fun if you didn’t write crap in the first place. But, that’s okay, because it’s perfectly okay for the Defective Perler to blame the tool for his shortcomings. We wouldn’t have jobs otherwise!

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Cut and paste another branch when you need it

People get all upset about long if-elsif chains, but if they’d just use a proper code editor with cut-n-paste and search, it’s really not all that bad. With split panes, multiple windows, and a big monitor, I can see hundreds of lines of code at once, so what’s your problem? Only got 24 rows? Get with the times, weirdo! Get a bigger monitor! Or maybe get some glasses if you can’t read the font size.

if( $hash{caseA} ) {
    some_sub( $hash{caseA} );
} elsif ( $hash{caseA} ) {
    some_sub( $hash{caseA} );
} elsif ( $hash{caseB} ) {
    some_sub( $hash{caseB} );
} elsif ( $hash{caseC} ) {
    some_sub( $hash{caseC} );
} elsif ( $hash{caseD} ) {
    some_sub( $hash{caseD} );
} elsif ( $hash{caseE} ) {
    some_sub( $hash{caseE} );
} elsif ( $hash{caseF} ) {
    some_sub( $hash{caseF} );
} elsif ( $hash{caseG} ) {
    some_sub( $hash{caseG} );
} elsif ( $hash{caseH} ) {
    some_sub( $hash{caseH} );
} elsif ( $hash{caseI} ) {
    some_sub( $hash{caseI} );
} elsif ( $hash{caseJ} ) {
    some_sub( $hash{caseJ} );
} elsif ( $hash{caseK} ) {
    some_sub( $hash{caseK} );
} elsif ( $hash{caseL} ) {
    some_sub( $hash{caseL} );
} elsif ( $hash{caseM} ) {
    some_sub( $hash{caseM} );
} elsif ( $hash{caseN} ) {
    some_sub( $hash{caseN} );
} elsif ( $hash{caseO} ) {
    some_sub( $hash{caseO} );
} elsif ( $hash{caseP} ) {
    some_sub( $hash{caseP} );
} elsif ( $hash{caseQ} ) {
    some_sub( $hash{caseQ} );
} elsif ( $hash{caseR} ) {
    some_sub( $hash{caseR} );
} elsif ( $hash{caseS} ) {
    some_sub( $hash{caseS} );
} elsif ( $hash{caseT} ) {
    some_sub( $hash{caseT} );
} elsif ( $hash{caseU} ) {
    some_sub( $hash{caseU} );
} elsif ( $hash{caseV} ) {
    some_sub( $hash{caseV} );
} elsif ( $hash{caseW} ) {
    some_sub( $hash{caseW} );
} elsif ( $hash{caseX} ) {
    some_sub( $hash{caseX} );
} elsif ( $hash{caseY} ) {
    some_sub( $hash{caseY} );
} elsif ( $hash{caseZ} ) {
    some_sub( $hash{caseZ} );
} else {
    print "No way!\n"
}

I could use something like a dispatch table or refactor the code, but that’s really a lot more work than adding another branch every time I have a new case, even if it does act like all of the other cases. No one has complained about it so far, so don’t rock the boat, you know? Besides, I probably won’t have to look at the code for another six months, so it’s someone else’s problem. Let them figure it out if they care so much about it. If they were so hot in Perl they’d just write some more Perl to generate that code.

print "if( \$hash\{caseA\} ) {\n";
print "    some_sub( \$hash\{caseA\} );\n";

foreach ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ) {
    $a = uc $_;
    print "\} elsif ( \$hash\{case$a\} ) {\n";
    print "    some_sub( \$hash\{case$a\} )\;\n";
}

print "\} else \{\n";
print "    print \"No way\!\\n\"\n";
print "\}\n";

Post to Twitter Post to Delicious Post to Digg Post to Facebook

print ‘Hello world!\n’;

Why write Effective Perl when you can complain about Defective Perl? Negativity is so much more cathartic and soul cleansing, plus you get to be really, really bitter about things you don’t really understand. You know you want to, after slaving all day fixing the mistakes of your coworkers, seeing hundreds of new and interesting Perl::Critic errors, and discovering the test suite is really just a series of pass() statements. That’s supposing that your coworkers use any of the tens of thousands of modules on CPAN, or even more than the five built-ins that they know. Or, worse yet, they’re converting everything to Moose because someone told them that it’s “modern” Perl.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Test for an empty string

Sometimes I need to see if there is anything in a string, so I looked for a random tutorial from someone I didn’t know to give me the answer, like http://w3mentor.com/learn/perl/perl-string-manipulation/test-empty-strings-in-perl/.

The defined operator is too much to type, so I can use some of the other options I found on that random page:

if($mystring) {
#variable is undefined
}
if($mystring eq undef) {
#variable is undefined
}

Dave Cross says those don’t work and everyone should just use defined.

Post to Twitter Post to Delicious Post to Digg Post to Facebook

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 = "buster@example.com";

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 "buster@example"
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_))}

Post to Twitter Post to Delicious Post to Digg Post to Facebook

Some books don’t even need an author

There’s no author listed on the cover or the spine of PERL Programming Interview Questions, Answers, and Explanations: Perl Programming Certification Review for ITCOOKBOOK.com, although you’ll find it’s edited by Emilee Newman Bowles. “Edited” might be a loose term, considering most of the content in the book is wholly lifted, without attribution or reference, from random content on the internet. Maybe she was the person to change all instances of “Perl” to “PERL”, but she didn’t follow her own advice in The Top 10 Mistakes when Writing Query Letters.

Here’s a real howler. What’s the difference between “Use” and “Require”? Even if they did get the capitalization correct, they don’t even steal the right content (which is in perlfaq8).


Here’s a page that they steal almost completely from a Slashdot interview answer by Larry Wall:


Post to Twitter Post to Delicious Post to Digg Post to Facebook