Perl best practice: prefer foreach to for

Perl problem: When you don’t use Perl every day, it’s hard to remember the combination of the for loop syntax and how to deal with the special $_ variable to refer to each element within the body of the loop.

Solution: As I write this today, I still can’t remember how to get this for loop and $_ syntax to work, at least not without pulling out a book, or looking it up on the internet. A much better solution is to just use Perl’s foreach syntax, and never look back.

Discussion

I just spent a few minutes trying to get the following Perl for loop to work, and got frustrated at wasting my time. As a warning, this code still does not work:

@files = qw(/foo/bar/file.pdf /foo/baz/file2.jpg);

# ERROR: I can't remember how to work with $_ in the following for loop
for (@files)
{
  # exclude any files in the /foo/bar hierarchy
  # this doesn't work because $_ is not getting assigned the way i expected ... argh ...
  next if /bar/;

  # print all other files
  print "$file\n";
}

The foreach loop fix

Fortunately just at that time my brain kicked in and said, “Quit screwing around with the for loop syntax, and just use the foreach syntax.” Fortunately I took my brain’s advice, and fixed the code like this, using the foreach syntax:

@files = qw(/foo/bar/file.pdf /foo/baz/file2.jpg);

foreach $file (@files)
{
  # exclude any files in the /foo/bar hierarchy
  next if $file =~ /bar/;

  # print all other files
  print "$file\n";
}

Note that in this example I don’t have to deal with the $_ variable. I just assign $file to each element in the @files array, and then refer to $file from within the body of the foreach loop.

Summary

As of today, I have no plans to ever use the Perl for operate ever again, certainly not in a situation like this. I can't remember the “special” syntax, unless I use Perl all the time, which I don’t any more. And the foreach loop syntax is much more readable.