2.18. Printing Correct PluralsProblem
You're printing something like " Solution
Use
printf "It took %d hour%s\n", $time, $time == 1 ? "" : "s";
printf "%d hour%s %s enough.\n", $time,
$time == 1 ? "" : "s",
$time == 1 ? "is" : "are";
Or, use the Lingua::EN::Inflect module from CPAN as described in the Discussion. Discussion
The only reason inane messages like "
If your noun changes by more than an printf "It took %d centur%s", $time, $time == 1 ? "y" : "ies"; This is good for simple cases, but you'll get tired of writing it. This leads you to write funny functions like this:
sub noun_plural {
local $_ = shift;
# order really matters here!
s/ss$/sses/ ||
s/([psc]h)$/${1}es/ ||
s/z$/zes/ ||
s/ff$/ffs/ ||
s/f$/ves/ ||
s/ey$/eys/ ||
s/y$/ies/ ||
s/ix$/ices/ ||
s/([sx])$/$1es/ ||
s/$/s/ ||
die "can't get here";
return $_;
}
*verb_singular = \&noun_plural; # make function alias
As you find more exceptions, your function will become increasingly convoluted. When you need to handle such morphological changes, turn to the flexible solution provided by the Lingua::EN::Inflect module from CPAN.
use Lingua::EN::Inflect qw(PL classical);
classical(1); # why isn't this the default?
while (<DATA>) { # each line in the data
for (split) { # each word on the line
print "One $_, two ", PL($_), ".\n";
}
}
# plus one more
$_ = 'secretary general';
print "One $_, two ", PL($_), ".\n";
__END__
fish fly ox
species genus phylum
cherub radius jockey
index matrix mythos
phenomenon formula
That produces the following:
This is one of the many things the module can do. It also handles inflections or conjugations for other parts of speech, provides number-insensitive comparison functions, figures out whether to use a or an , and plenty more. See AlsoThe ternary ("hook-colon") operator discussed in perlop (1) and in the "Conditional Operator" section of Chapter 2 of Programming Perl ; the documentation with the CPAN module Lingua::EN::Inflect |
|