Smarter scripts: Command-line switches

  1. Help!
  2. Smarter scripts
  3. Case sensitivity

So now we have a script with one command-line switch, but switches are like potato chips: once you start, you can’t have just one. Here’s an example: we’ve currently made our script case-insensitive, so that we don’t have to worry about remembering the exact case of the text we’re looking for. But what if we want it to be case-sensitive? Let’s add a case switch.

To do this, though, we’re going to need to “generalize” our search for command-line switches. If we just have a series of ifs, that will mean that either we can’t have more than one command-line switch, or we have to put them in an exact order. That will always be too difficult to remember, especially when we have eight or more switch possibilities.

One way of doing this is to loop through the beginning arguments as long as the argument is a switch. Stop looping when it is no longer a switch. We can use a while block for this. Replace our help switch’s five lines with:

#strip off the command-line switches and act on or remember them
while ($ARGV[0] =~ /^--(.+)/) {
$switch = $1;

#pull this switch off of the front of the list
shift;

#if they ask for help, do it and exit
if ($switch eq "help") {
help();
exit;
}
}

This snippet does the same thing as the previous “help-only” snippet, but it will allow us to add any switches we want.

while ($ARGV[0] =~ /^--(.+)/) {

The “=~” is new. It is used to match a scalar variable against a regular expression. The variable goes on the left, and the regular expression goes on the right.

And what a regular expression! Let’s take it piece by piece.

It begins with a caret, or “hat” character. The caret marks the beginning of a piece of text. Whatever comes next in the regular expression will only match if it comes at the beginning of the text. So, since the next two characters are two dashes, two dashes will only match if the two dashes are at the beginning. This differs from our previous regular expressions, where the text we specified could occur anywhere on the line.

After the two dashes, we have “(.+)”. The parentheses are easy: they tell Perl to remember that part of the match, whatever it is. We’ll see what that means in a moment.

The period, or “dot”, matches a single character. It can be any character.

The plus sign matches one or more of the previous piece of the regular expression. The previous piece is the dot, so the dot and the plus means one or more of any character.

Taken as a whole, this regular expression will match --help, --switch, --q, --rain, or even --planet-99x. It will not match help--, switch--station, or anything else that does not begin with two dashes.

$switch = $1;

The next line assigns the value of the variable $1 to the variable $switch. After a regular expression, Perl remembers any items in parentheses, and it remembers them by putting them into $1, $2, $3, $4, etc., on up to however many sets of parentheses were in the regular expression. We only have one set of parentheses, so we only get $1.

Because our parentheses were after the two dashes, $switch will now contain the part of that switch not including the initial two dashes.

#pull this switch off of the front of the list
shift;

We’ve already used shift. It shifts an item off of the front of a list. By default, it shifts it off of the front of the list of command-line arguments. Since @ARGV is the list of arguments, shift shifts the first argument off of @ARGV. Once shifted off, that first argument is gone. What used to be the second argument is now the first argument. This gets us ready for the next turn through the loop. $ARGV[0] is now the next argument.

#if they ask for help, do it and exit
if ($switch eq "help") {
help();
exit;
}

This section looks very familiar. The only part that’s changed is the if line. Instead of checking to see if $ARGV[0] is equal to “--help”, we’re checking to see if $switch is equal to “help”. If it is, we call the help subroutine and exit the script.

  1. Help!
  2. Smarter scripts
  3. Case sensitivity