Functions
- 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}) { $card_map{$num}; # return value } else { $num; # return value } } # driver routine: while (<>) { chomp; print "card of $_ is ", &card($_), "\n"; }
The
&cardsubroutine (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}issix; consequently, the mapping is easy.The
ifstatement 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$numis or-4), the value returned from the hash lookup isundef, so theelse-branch of theifstatement is executed, returning the original number. You can also replace that entireifstatement 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$numis out of range), the right side of the||operator is evaluated, returning$numas the return value.The driver routine takes successive lines,
chomping off their newlines, and hands them one at a time to the&cardroutine, printing the result. - Here's one way to do it:
sub card { ...; } # from previous problem print "Enter first number: "; chomp($first = <STDIN>); print "Enter second number: "; chomp($second = <STDIN>); $message = &card($first) . " plus " . &card($second) . " equals " . &card($first+$second) . ".\n"; print "\u$message";The first two
printstatements prompt for two numbers, with the immediately following statements reading the values into$firstand$second.A string called
$messageis then built up by calling&cardthree times, once for each value, and once for the sum.After the message is constructed, its first character is uppercased by the case-shifting backslash operator
u. The message is then printed. - Here's one way to do it:
sub card { my %card_map; @card_map{0..9} = qw( zero one two three four five six seven eight nine ); my($num) = @_; my($negative); if ($num < 0) { $negative = "negative "; $num = - $num; } if ($card_map{$num}) { $negative . $card_map{$num}; # return value } else { $negative . $num; # return value } }Here, we've given the
%card_maparray a name for 0.The first
ifstatement inverts the sign of$num, and sets$negativeto the word negative, if the number is found to be less than 0. After thisifstatement, the value of$numis always non-negative, but we will have an appropriate prefix string in$negative.The second
ifstatement determines if the (now positive)$numis within the hash. If so, the resulting hash value is appended to the prefix within$negative, and returned. If not, the value within$negativeis attached to the original number.That last
ifstatement can be replaced with the expression:$negative . ($card_map{$num} || $num);