I've used this in most CGIs (from a personal ~/lib/Tools.pm) as a way of human formatting missing fields or other list-ish items back to the user. It's a bit obfuscated but I've never needed to change it so I like it better this way.
Update (15 Aug 2004) Template Toolkit version added.
sub serial {
join(', ', @_[0..$#_-1]) .
(@_>2 ? ',':'' ) .
(@_>1 ? (' and ' . $_[-1]) : $_[-1]);
}
NB: removed prototype (@) from sub because as Aristotle pointed out it wasn't really doing anything.
sample usage
my @primate = qw( sifaka gibbon tarsier langur );
print "Endangered primates: ", serial(@primate), ".\n";
Endangered primates: sifaka, gibbon, tarsier, and langur.
Update: Serial comma virtual method with Template Toolkit (same code, different use). Found I missed it when moving to TT2 so discovered how to transplant it.
# in some parent formatting, template processing module
use Template; # not actually using it in the code here
use Template::Stash;
$Template::Stash::LIST_OPS->{ serial } =
sub {
my @list = @{ +shift || [] };
join(', ', @list[0..$#list-1]) .
(@list>2 ? ',':'' ) .
(@list>1 ? (' and ' . $list[-1]) : $list[-1]);
};
Now in TT code you can do this with lists:
Hey, Joe. Where you going with that
[% user.ListOfItems.serial %] in your hand?