Perl Tips Grab Bag No. 1

Sep 19, 2007

Another new recurring feature I'm going to try out here at the site are programming tip 'grab bags.' These will often feature a few tips I've picked up over the years, which I find highly useful. We'll start out this inaugural article with a few Perl tips:

1. Don't parse command line options yourself

One thing I've learned a number of times over is to never parse command line options yourself. Why? Because the Getopt::Long and Getopt::Std modules do it for you (and they make it both easy and convenient). These standard modules allow you to store away your command line options either in separate variables, or in a hash. There are times you'll want to use Getopt::Long over Getopt::Std (and vice-versa), so know the differences between the two. Either one will save you lots of time and headache. Here's one way to make use of this module:

use Getopt::Std;

our($opt_c, $opt_d, $opt_t);
getopts("cdt:");

my $filename = shift;

This tiny snippet parses the given command line parameters, looking for either a 'c', a 'd', or a 't' option. In this example, the 'c' and 'd' options are flags and the 't' option expects a user supplied value (note the trailing colon). If the user passes either '-c' or '-d' on the command line, the $opt_c and $opt_d variables will get set appropriately (otherwise, they remain null). Likewise, if the user passes a '-t' on the command line, the $opt_t variable gets set to the value the user passed in (so the user would need to type something like myScript.pl -t someValue). Otherwise, $opt_t remains null. Also note that we are still able to retrieve other values passed in via the command line (in this example, a filename). Quite handy!

One other hidden benefit of the Getopt modules is the fact that they handle combined options. So, myScript.pl -cd would parse just the same as myScript.pl -c -d. Doing this kind of parsing by hand would be tricky, so don't try to do it. Let Getopt do all the work for you.

Getopt::Long allows for long options (which make use of the double dash, such as --verbose), but it can also handle single letter options. Storing options in a hash is also available to both modules, making it very easy to set up if you have lots of options to parse.

2. Use printf (or variants) to print plurals

This tip comes from the excellent Perl Cookbook, and I've used it a number of times. Use either the printf or sprintf functions to handle printing the proper plural (or singular) of a value. For example:

printf "%d item%s returned", $size, $size == 1 ? "" : "s";

If there were only 1 item, we would print out 1 item returned. Likewise, if we printed out 2 or more items, 2 items returned (note the trailing 's'). You can use this trick to print the proper plural for words that have strange plurals, like "goose" and "geese."

3. Use File::Spec to handle cross platform file paths

The File::Spec module and its children allow one to easily make cross-platform file paths, useful for those scripts which must operate across operating systems. In one project at work, I made use of the File::Spec::Functions module, which exports a number of handy functions. I find the catfile function very handy, and I use it like so:

my $logFile = catfile('weeklybuild', 'log', 'build.log');

The function takes care of putting the right separators between the values (backslash for Windows, forward slash for Linux, and colons for the Mac).

2 Comments

kip

2:31 PM on Sep 20, 2007
For the third one, I've always converted all paths to use forward slashes with $path =~ s{\\}{/}g;. All the Perl functions seem to work fine with forward slashes on Windows. Of course, this method would break if I ever had a filename on Unix that actually had a backslash in it (which is valid). Or if I needed to let the OS handle the path (say, if I printed it out as a parameter to a function). I was also unaware that colons were the path separator for Mac, I had assumed it was the same as Unix since it's based on BSD.

Jonah

12:14 AM on Sep 21, 2007
The new Mac operating systems might use slash, but the File::Spec documentation mentions colons. Kinda weird, huh? One other benefit of File::Spec is that it can give you paths to the root directory ('/' on Unix systems, 'C:\' on Windows, and who knows what on the Mac). There are some other equally useful handy functions available.

Leave a Comment

Ignore this field:
Never displayed
Leave this blank:
Optional; will not be indexed
Ignore this field:
Both Markdown and a limited set of HTML tags are supported
Leave this empty: