NB: These pages were mostly written in 2001 or so. The résumé dates are accurate but the code is aged and unlike whiskey, 8 year-old code doesn't usually taste better. For a look at my current skills and to see my CPAN modules, sample code, and code discussions, please see these pages instead: Perl resources and sample code and PangyreSoft.
serial(), serial comma join function
Social links
View Ashley Pond V's profile on LinkedIn
Miscellaneous
Why you should use the serial comma

As Teresa Nielsen Hayden reminds us in Making Book, it avoids ambiguities like this:

"I dedicate this work to my parents, Ayn Rand and God."


Other pages

Description

A serial comma join function. It takes a list and returns it as a string with serial commas and an “and” if appropriate. serial(“fish”, “cat”, “dog”) would return “fish, cat, and dog”. serial(“fish”, “gold”) would return “fish and gold”. serial(“fish”) would merely return “fish” since there is nothing to glue together with commas or a conjunction. serial() is extremely useful for returning lists in a human readable fashion, like search results, aggregated error messages, or CGI prompts.

Code
Usage
my @primate = qw( sifaka gibbon tarsier langur );

print "Endangered primates: ", serial(@primate), ".\n";
Endangered primates: sifaka, gibbon, tarsier, and langur.
@primate = qw( sifaka langur );

print "Endangered primates: ", serial(@primate), ".\n";
Endangered primates: sifaka and langur.

Discussion

This is a case where the code is terse and somewhat obfuscated in the repeated ternary calls ( A ? B : C ) and the negative array indices. Condensed idiomatic code can be avoided in favor of clearer, expansive code most of the time. This makes for easier maintainability as future coders might need to deal with the code in a hurry or without a high level of expertise. Still, ternary operations are often perfect for embedding grammatical choices in code. Eg: (to get a correct plural “s”):

printf "You have %d item%s in your cart.\n", 
    $count,
    $count == 1 ? '' : 's';

In the case of serial() the code is sufficiently compact of purpose and use to have no real gain in being spelled out in 20 lines of more obvious code. There is no maintenance issue with code this specific. It does what it does and won’t ever need repair. Besides, seeing it done so compactly is a more interesting exercise. With sufficient comments the code can be illuminated and retain its compact charm.

As a side note, it would be easy to extend it to behave more like join(). We’d just add a ($) arg before the (@) so you could pass the conjunction (and, but, or, “anything you want”) and not be stuck with the default “and.” In fact, it’s so easy, let’s do it.

New Code
New usage
my @dogs = qw( danes afghans wolfhounds chihuahuas );

print "Which do you prefer? ";
print ucfirst serial("or", @dogs);
print "?\n";
Which do you prefer? Danes, afghans, wolfhounds, or chihuahuas?
my @fish = qw( cichlids goldfish cardinals piranha );

print "I love ";
print serial("but not", @fish), ".\n";
I love ciclids, goldfish, cardinals, but not piranha.

Additional implementation in JavaScript

There is also a nice Array() class prototype extention for doing serial joins with JavaScript here.

Search these pages via Google
Text, original code, fonts, and graphics ©1990-2009 Ashley Pond V.