Call 1-800-Confuse-Me

If you’re like me, you hate people who give out phone numbers containing only letters—for example: 1-800-555-junk. Dialing this is a slow process. It’s much easier to dial the numbers: 1-800-555-5865. (Please don’t dial this number, I made it up.)

Perl comes to the rescue and lets you convert alphanumeric phone numbers into real ones.

The phone.pl program (see Listing 16.2) takes a letter phone number on the command line and outputs a numeric version. The basic algorithm is to split apart the argument into individual letters and then process them through a translation hash.

The only tricky part is turning a string such as “junk” into an array such as (“j”, “u”, “n”, “k”). The natural solution when you need to break up something is to look at the unpack function. But after looking at the documentation for unpack and experimenting with many different packing specifications, I concluded that unpack just wouldn’t work. Sometimes the natural solution is not the correct one in Perl.

I remembered the split function. Specifically, what happens if someone tries to use the following statement to split a line into a bunch of words is something like the following:

# Classic mistake 
my @words = split /s*/, $line;

This does not split the words at whitespace (s) boundaries because the * says 0 or more times, and Perl likes to choose. The result is that this line gets split into single characters. (See Chapter 3, “Arrays,” if you’ve forgotten about this.)

So split works if used properly. But what should you use as a field separator? The answer is nothing. You want every character to be a field. So to split the argument into single characters, use this statement:

49    my @chars = split //, $string;

That being done, all you need are some loops and print statements, and you’re in business.

Listing 16.2. phone.pl
 1    =pod 
 2 
 3    =head1 NAME 
 4 
 5    phone.pl – Turn alphabetic phone numbers into numbers 
 6 
 7    =head1 SYNOPSIS 
 8 
 9        perl phone.pl <number–string> 
10 
11    =head1 DESCRIPTION 
12 
13    The I<phone.pl> program turns phone numbers containing letters 
14    into something you can dial.  For example: 
15 
16            1–800–POORNUM 
17 
18    becomes 
19 
20            1–800–7667686 
21 
22    =cut 
23    use strict; 
24    use warnings; 
25 
26    # A hash  keys=letters, values=numbers 
27    my %xlate = (
28        'a' => 2, 'b' => 2, 'c' => 2, 
29        'd' => 3, 'e' => 3, 'f' => 3, 
30        'g' => 4, 'h' => 4, 'i' => 4, 
31        'j' => 5, 'k' => 5, 'l' => 5, 
32        'm' => 6, 'n' => 6, 'o' => 6, 
33        'p' => 7, 'q' => 7, 'r' => 7, 's' => 7, 
34        't' => 8, 'u' => 8, 'v' => 8, 
35        'w' => 9, 'x' => 9, 'y' => 9, 'z' => 9, 
36        'A' => 2, 'B' => 2, 'C' => 2, 
37        'D' => 3, 'E' => 3, 'F' => 3, 
38        'G' => 4, 'H' => 4, 'I' => 4, 
39        'J' => 5, 'K' => 5, 'L' => 5, 
40        'M' => 6, 'N' => 6, 'O' => 6, 
41        'P' => 7, 'Q' => 7, 'R' => 7, 'S' => 7, 
42        'T' => 8, 'U' => 8, 'V' => 8, 
43        'W' => 9, 'X' => 9, 'Y' => 9, 'Z' => 9); 
44 
45    # Put together all the arguments as one big string 
46    my $string = join ' ', @ARGV; 
47 
48    # Now split things up into characters 
49    my @chars = split //, $string; 
50 
51    # Go through each character and translate it 
52    foreach my $cur_char (@chars) 
53    {
54        if (defined($xlate{$cur_char})) {
55            print $xlate{$cur_char}; 
56        } else {
57            print $cur_char; 
58        } 
59    } 
60    print "
"; 
61 
62

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset