pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
Philip Newton ([personal profile] pne) wrote in [site community profile] dw_dev_training 2012-02-06 02:12 pm (UTC)

OK, here are the two big thoughts I had.

$num_args = $#ARGV + 1;

An array in scalar context evaluates to the number of its elements, so this could be $num_args = @ARGV; instead.

I like to separate $#foo and scalar @foo, and use the former only in contexts where it means "index of the last entry" (for example, in a for loop iterating over the indices of an array) and the latter when I want a number of elements.

(Also, $#foo is sensitive to setting $[, but you shouldn't mess with that variable anyway.)

The other one is that "iterating over the files in @ARGV" is such a common use case that Perl has a shortcut for this.

If you read from the empty filehandle (as in while (<>) with nothing in between the angle brackets), you'll get a line at a time from all of the files in succession. Perl will automatically handle opening them and closing them for you. And if you didn't supply any file names, Perl will read from standard input. (This is a bit like Unix tools such as gzip or grep which will also work on standard input if there are no file name arguments.) See http://perldoc.perl.org/perlop.html#I/O-Operators for more on this. (That also mentions that you can find out which file you're currently on by examining $ARGV, which the magic will set for you appropriately on each new file.)

And if you don't assign <> to anything in the while loop, it'll automatically assign to $_ - which is the default thing that s/// operates on, which can be handy. It's also the default operand for lots of other operations.

So if you were just reading from the files, you could replace the whole "# Have files to parse..." loop with:

while (<>) {
  s/\t/        /;
}


That would just be missing the printing of the changed line and the editing behaviour.

In the one-liner I suggested, these are supplied by the -p and the -i command-line switch, respectively; see http://perldoc.perl.org/perlrun.html for more information on those.

You can also turn on -i inside the program by assigning to the magic variable $^I.

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting