2.18. Printing Correct PluralsProblemYou're printing something like " SolutionUse 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. DiscussionThe 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 aliasAs 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 |