Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

pluralization

by Vynce (Friar)
on Sep 09, 2005 at 01:06 UTC ( [id://490387]=CUFP: print w/replies, xml ) Need Help??

not always what you want, but a cute way to approach a standard data presentation issue -- and who can resist use of the x operator?
my $noun = 'iteration'; for my $count (0..2) { my $declension = 's' x (abs($count) != 1); print "$count $noun$declension so far...\n"; }

Replies are listed 'Best First'.
Re: pluralization
by liverpole (Monsignor) on Sep 09, 2005 at 01:48 UTC
    Interesting, for sure.  I've always favored the pithier version of:
    for my $count (0..2) { my $s = (1 == $count)? "": "s"; print "$count iteration$s so far...\n"; }
    Of course, it's gotta be tweaked under certain circumstances:
    for my $cheese_eaters (0..2) { my $noun = (1 == $count)? "mouse": "mice"; print "$cheese_eaters $noun so far...\n"; }
    By the way, the (<constant> == $count) is a habit I picked up from a company which had some good ideas about coding guidelines.  (It was for C, but applies to Perl as well).  The idea is that you can never accidentally write '=' instead of '==' because the compiler will detect an attempt to assign to a constant and forbid it outright.

      i think the x notation should theoretically be faster, because there is no branch -- just a repeat some (possibly zero) number of times.

      LHS constants for comparison to avoid assignment is a pretty cool habit. perhaps perlmonks should have a "habits & practices" section.

        I'm not sure I completely agree.  The 'x' operator still has to perform a conditional evaluation at a lower level, and 'abs' will certainly chew up some time.  Here's what I get when I benchmark it:

        Program 'benchmark.pl':

        #!/usr/bin/perl -w # Strict use strict; use warnings; # User-defined my $niter = 2000000; # Libraries use Benchmark; # Main program timethis($niter, \&sub1); timethis($niter, \&sub2); # Subroutines sub sub1() { my $noun = 'iteration'; for my $count (0..2) { my $declension = 's' x (abs($count) != 1); my $result = sprintf "$count $noun$declension so far...\n"; } } sub sub2() { for my $count (0..2) { my $s = (1 == $count)? "": "s"; my $result = sprintf "$count iteration$s so far...\n"; } }

        Results:

        [liverpole@diamond<28>]% benchmark.pl timethis 2000000: 25 wallclock secs (20.27 usr + 0.05 sys = 20.32 CPU +) @ 98425.20/s (n=2000000) timethis 2000000: 19 wallclock secs (17.12 usr + 0.01 sys = 17.13 CPU +) @ 116754.23/s (n=2000000)

        Of course, I had to change "print" statements to "sprintf", since the program will be ridiculously I/O-bound otherwise.  But since I had to resort to an absurd iteration count anyway, it probably doesn't matter which you use for most cases.

        Hey, I love your idea about a Perlmonks "habits & practices" section!  If something like that existed, I would reference it all the time.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://490387]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-19 19:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found