It isn’t that difficult to trip up the script we’ve got so far. If you just type ./show and press return, not only does it wait on the command line for us to type something, it doesn’t even know that we didn’t tell it to search for anything.
Often, when you can identify command line arguments that you know are wrong, you will want to check for those arguments, and print instruction text when someone types something unexpected.
In this case, if there is nothing to search for, the person using the script probably doesn’t know how to use the script. We can tell them how to use it. Change the script by adding an “if” line above the “while”, indenting everything, and then adding several lines at the bottom:
#!/usr/bin/perl
#Search for songs in a file of the following tab-separated data:
# title, duration, artist, album, year, rating, rip date, track position, genre
#the first item on the command line is what we're searching for
if ($searchFor = shift) {
while (<>) {
#split out the song, duration, artist, and album
($song, $duration, $artist, $album) = split("\t");
#print the information if this line contains our search text
print "$song ($album, by $artist)\n" if /$searchFor/i;
}
} else {
help();
}
#describe how this script is used
sub help {
print "Syntax: show <search text> [song files]\n";
print "\tSearch for <search text> in the song file. If no song file is specified\n";
print "\t'show' will expect it on standard input.\n";
print "\tA song file is a tab-delimited file with:\n";
print "\ttitle, duration, artist, album, year, rating, rip date, track position, genre\n";
}
The word “if” starts a block very much like the word “while” does. Unlike while, however, an if block is only performed once. Otherwise it is very similar. If the expression inside the parentheses of the if line returns something, the if block is performed. Otherwise, it isn’t. Some if blocks have a corresponding else block. If so, the else block is only performed if the if block is not performed.
Notice how the while block is indented further beyond the indentation of the if block. I indented it further once I placed the if block around it. You should do so also. As your scripts become more and more complex, failure to indent will make it practically impossible to fix errors.
The word “sub” also starts a block. Unlike while and if, however, a sub block is never performed unless asked. The word that follows sub is the name of this subroutine. It is how we ask Perl to perform this block. Anywhere where we have that name followed by two parentheses, Perl will perform the sub block corresponding to that name.
In our case, if the shift does not assign something into $searchFor, we call the help subroutine. The term subroutine is somewhat archaic. We almost never use the term routine anymore, and even subroutine is fading from use. But that’s the origin of the word sub to mark these blocks of Perl lines.