His Perl could have been tightened up considerably.
Boy, is that a call to action! I can't believe I'm the first in 4 years to have taken it up …. Here's a more-or-less faithful copy:
use strict;
use warnings 'all';
use constant {
EMAIL => 17,
CONTACTME => 27,
SKUTITLE => 34
};
my @records; # Arrays are initialised empty; no need to do it explicit
+ly.
push @records, [ split "\t" ] for <>;
do { tr/"//d for @$_ } for @records;
my @contact_records;
do { push @contact_records, [ @$_[ SKUTITLE, CONTACTME, EMAIL ] ] if $
+_->[CONTACTME] == 1 } for @records;
{
local $, = "\t";
local $\ = "\n";
print @$_ for sort { $a->[0] cmp $b->[0] } @contact_records;
}
To me, this task suffers, rather than benefits, from the names, and is much better suited for a Unix-style pipeline; fortunately, Perl is good at those (although I resort to substr to avoid the to-me unsatisfying s///; $_):
use strict;
use warnings 'all';
use constant {
EMAIL => 17,
CONTACTME => 27,
SKUTITLE => 34
};
{
local $, = "\t";
local $\ = "\n";
print @$_ for
sort { $a->[0] cmp $b->[0] }
grep { $_->[1] }
map {
chomp;
[
map { substr $_, 1, -1 }
( split "\t" )[ SKUTITLE, CONTACTME, EMAIL ]
]
} <>;
}
I've replaced the test for whether the
CONTACTME field
== 1 (not
eq "1", ugh) with a test for whether it's true, since that's almost certainly what was meant; but it's easy to change it back.
Finally, note that, since the CONTACTME field is not carrying any useful information, we might as well avoid printing it; so we could define
sub snip_or_toss { $_[CONTACTME] ? @_[ SKUTITLE, EMAIL ] : () }
replace the outer
map by
map { chomp; [ map {...} snip_or_toss split "\t" ] }, and then get rid of the
grep.