• Aucun résultat trouvé

Handling switches: -s

Dans le document Minimal Perl (Page 65-68)

Perl essentials

2.4 W RITING SIMPLE SCRIPTS

2.4.3 Handling switches: -s

To let a script work on different data items on different invocations—such as Homer’s email address on the first run and Marge’s on the second—words with a special signifi-cance, called arguments, can be presented after the script’s name.

As a case in point, the following invocation of a custom script shows how one fic-titious IT manager displays her appreciation for her most outstanding software developers (who have quirky login names). Last year, the script was invoked with squidward, gandalf, and peewee as arguments, but this time, different develop-ers have been chosen for special recognition:

$ award_cruises 'slurm' 'gollum' 'kryten' # argument order critical 'gollum' awarded Alaska cruise

'slurm' awarded Panama Canal cruise 'kryten' awarded Perlistan Riviera cruise

The programmer named in the first argument gets the Panama Canal cruise, the sec-ond the Alaska Inside Passage cruise, and the third the Perlistan Riviera cruise (around the desiccated Lake Perlistan; that’s a punishment!). This design requires the program-mer to know how to access command-line arguments manually, and the user to present them in exactly the right order—or the wrong developer gets the booby prize.

Fortunately, Perl provides an easier alternative, based on the s option for automatic processing of switch arguments (a.k.a. switches). By supporting the use of switches such as –perlistan, this enhanced version of the earlier script becomes easier to use:

$ award_cruises2 -perlistan='kryten' -panama='slurm' \

> -alaska='gollum' # argument order is now unimportant 'gollum' awarded Alaska cruise

'slurm' awarded Panama Canal cruise 'kryten' awarded Perlistan Riviera cruise

The effect of each switch argument is to assign a value to a like-named switch variable in the program. Here’s the part of the award_cruises2 script that prints the values of its switch variables:

print "'$alaska' awarded Alaska cruise";

print "'$panama' awarded Panama Canal cruise";

print "'$perlistan' awarded Perlistan Riviera cruise";

The major benefit of this improved version is that it allows cruises to be associated with developers through use of the –cruise-name=User-ID switch syntax, which frees the user (and the programmer) from worrying about the argument order.

The upper portion of table 2.5 shows the two formats for switches and explains their differences. The lower portion describes the use of the our declaration to mark switches as optional.

The -name format is used for switches of the on/off type, where all that matters is detecting the switch’s presence via a True value or absence via False. For example, script –debug sets $debug to a True value within script.

-name='stuff' Sets $name to stuff.

This format is used for switches that need to have particular values associated with their variables. For example, script -email='a@b.ca' sets $email to that address.

Syntax in script Effect Comments

Switches that are optional should have their variables listed in our statements at the top of the script, to prevent Perl from issuing warnings when they aren’t used.

To list more than one switch variable in a single our statement, insert commas between them and parentheses around them.

a. Switches are implemented as scalar variables, so any combination of letters, digits, and underscores can be used in forming a switch name—but the first character should be a letter. When the -name=stuff format is used, proper Shell-level quoting must be used on stuff—single quotes are appropriate for literal values.

Now you can understand how award_cruises2 works. It employs the s option, and, as you saw earlier, it was invoked with the variable-assignment style of switch syntax (e.g., -panama='slurm'). The = symbol makes it clear that the effect of this switch is to request the assignment of the indicated value to the associated switch vari-able within the program. In this way, $panama got set to “slurm” with the earlier invocation, $alaska to “gollum”, and $perlistan to “kryten”, allowing the pro-grammer to access those variables to see who will be cruising where.

Being able to handle command-line switches in such a convenient manner is one of the features that makes Perl so easy to use. You’ll see a complete example of a sim-ple switch-using script next.

A switch-driven line-numbering script: show_files

The cat-like show_files script recognizes a -line_numbers (“show line num-bers”) switch, which causes the script to insert each line’s number before its contents.

Because there’s no need to set the associated variable ($line_numbers) to any par-ticular value, the -name syntax is used instead of -name='stuff' (see table 2.5), causing the variable to be set to a True value.

Here are some sample runs of show_files:

$ show_files gilliam_movies # "-line_numbers" switch not used Time Bandits

12 Monkeys The Fisher King

$ show_files -line_numbers gilliam_movies # switch used 1: Time Bandits

2: 12 Monkeys 3: The Fisher King

Note that switches must come before filenames on the command line; otherwise, perl interprets them as filenames:

$ show_files gilliam_movies –line_numbers # switch misplaced Time Bandits

12 Monkeys The Fisher King

Can't open -line_numbers: No such file or directory ...

Here’s the script—notice the -s argument on its shebang line:

$ cat show_files

#! /usr/bin/perl -s -wnl

# Usage: show_files filename

# show_files -line_numbers filename (for line numbers) our ($line_numbers); # makes -line_numbers optional

$line_numbers and printf "$.: "; # if switch provided, print line # number, without newline print; # print current line with newline

This script can print a line-number prefix before each line, but it does so only when the $line_numbers variable is True (reflecting the presence of the -line_numbers switch on the command line). The conditionality of the printf statement on the value of the switch variable is expressed by the logical and operator (discussed in section 2.4.5), which has an “if/then” meaning here (like the Shell’s &&).

Notice that the switch variable is named in an our statement, which has the effect of making that switch optional.12

A different approach is required for programs that have mandatory switches.

An example is award_cruises2, shown earlier, which requires all of -panama, -perlistan, and -alaska to be set on each run (perhaps because the com-pany gets a discount for triple bookings). In such cases, no our declarations should be made for the variables associated with required switches. This allows a warning to be generated for any switch that is omitted, calling the user’s atten-tion to the mistake.

For example, here’s what happens when the award_cruises2 script is run with-out the -alaska=User-ID switch:

$ award_cruises2 -perlistan='kryten' -panama='slurm' # -alaska?

Name "main::alaska" used only once: possible typo ...

The “used only once” message is triggered because the script is being asked to retrieve the value of the variable $alaska, without the value first being set by a correspond-ing switch argument on the command line. In this way, the user is alerted to her incorrect usage and given a (somewhat vague) indication of what was missing.

You’ll see techniques for presenting custom diagnostic messages that are even more helpful next.

Dans le document Minimal Perl (Page 65-68)