A.7. Chapter 8

  1. Here's one way to do it:

    						sub card {
        my %card_map;
        @card_map{1..9} = qw(
            one two three four five six seven eight nine
        );
    
        my($num) = @_;
        if ($card_map{$num}) {
           return $card_map{$num};
        } else {
          return $num;
        }
    }
    # driver routine:
    while (<>) {
        chomp;
        print "card of $_ is ", &card($_), "\n";
    }

    The &card subroutine (so named because it returns a cardinal name for a given value) begins by initializing a constant hash called %card_map. This array has values such that $card_map{6} is six, making it fairly easy to do the mapping.

    The if statement determines if the value is in range by looking the number up in the hash: if there's a corresponding hash element, the test is true, so that array element is returned. If there's no corresponding element (such as when $num is 11 or -4), the value returned from the hash lookup is undef, so the else-branch of the if statement is executed, returning the original number. You can also replace that entire if statement with the single expression:

    $card_map{$num} || $num;

    If the value on the left of the || is true, it's the value for the entire expression, which then gets returned. If it's false (such as when $num is out of range), the right side of the || operator is evaluated, returning $num as the return value.

    The driver routine takes successive lines, chomping off their newlines, and hands them one at a time to the &card routine, printing the result.

  2. Here's one way to do it:

    sub card { ...; } # from previous problem print "Enter first number: ...

Get Learning Perl, Second Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.