Printing Correct Plurals
Problem
You’re printing something like "It
took
$time
hours"
, but "It
took
1
hours"
is ungrammatical. You would like to get it
right.
Solution
Use printf
and a ternary conditional
(X
?
Y
:
Z
) to alter the noun or verb:
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 "1
file(s)
updated"
appear is
because their authors are too lazy to bother checking whether the
count is 1 or not.
If your noun changes by more than an "-s"
,
you’ll need to change the printf
accordingly:
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? ...
Get Perl Cookbook 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.