One of my colleagues recently interviewed some candidates for a job and one said they had very good Perl experience.
Since my colleague didn't know Perl, he asked me for a critique of some code written (off-site) by that potential hire, so I had a look and told him my concerns (the main one was that it originally had no comments and it's not like we gave them enough time).
However, the code works so I'm loathe to say no-go without some more input. Another concern is that this code basically looks exactly how I'd code it in C. It's been a while since I did Perl (and I didn't do a lot, I'm more a Python bod for quick scripts) but I seem to recall that it was a much more expressive language than what this guy used.
I'm looking for input from real Perl coders, and suggestions for how it could be improved (and why a Perl coder should know that method of improvement).
You can also wax lyrical about whether people who write one language in a totally different language should (or shouldn't be hired). I'm interested in your arguments but this question is primarily for a critique of the code.
The spec was to successfully process a CSV file as follows and output the individual fields:
User ID,Name , Level,Numeric ID
pax, Pax Morgan ,admin,0
gt," Turner, George" rubbish,user,1
ms,"Mark \"X-Men\" Spencer","guest user",2
ab,, "user","3"
The output was to be something like this (the potential hire's code actually output this):
User ID,Name , Level,Numeric ID:
[User ID]
[Name]
[Level]
[Numeric ID]
pax, Pax Morgan ,admin,0:
[pax]
[Pax Morgan]
[admin]
[0]
gt," Turner, George " rubbish,user,1:
[gt]
[ Turner, George ]
[user]
[1]
ms,"Mark \"X-Men\" Spencer","guest user",2:
[ms]
[Mark "X-Men" Spencer]
[guest user]
[2]
ab,, "user","3":
[ab]
[]
[user]
[3]
Here is the code they submitted:
#!/usr/bin/perl
# Open file.
open (IN, "qq.in") || die "Cannot open qq.in";
# Process every line.
while (<IN>) {
chomp;
$line = $_;
print "$line:\n";
# Process every field in line.
while ($line ne "") {
# Skip spaces and start with empty field.
if (substr ($line,0,1) eq " ") {
$line = substr ($line,1);
next;
}
$field = "";
$minlen = 0;
# Detect quoted field or otherwise.
if (substr ($line,0,1) eq "\"") {
$line = substr ($line,1);
$pastquote = 0;
while ($line ne "") {
# Special handling for quotes (\\ and \").
if (length ($line) >= 2) {
if (substr ($line,0,2) eq "\\\"") {
$field = $field . "\"";
$line = substr ($line,2);
next;
}
if (substr ($line,0,2) eq "\\\\") {
$field = $field . "\\";
$line = substr ($line,2);
next;
}
}
# Detect closing quote.
if (($pastquote == 0) && (substr ($line,0,1) eq "\"")) {
$pastquote = 1;
$line = substr ($line,1);
$minlen = length ($field);
next;
}
# Only worry about comma if past closing quote.
if (($pastquote == 1) && (substr ($line,0,1) eq ",")) {
$line = substr ($line,1);
last;
}
$field = $field . substr ($line,0,1);
$line = substr ($line,1);
}
} else {
while ($line ne "") {
if (substr ($line,0,1) eq ",") {
$line = substr ($line,1);
last;
}
if ($pastquote == 0) {
$field = $field . substr ($line,0,1);
}
$line = substr ($line,1);
}
}
# Strip trailing space.
while ($field ne "") {
if (length ($field) == $minlen) {
last;
}
if (substr ($field,length ($field)-1,1) eq " ") {
$field = substr ($field,0, length ($field)-1);
next;
}
last;
}
print " [$field]\n";
}
}
close (IN);