Perl Advent Calendar 2008-12-06

Baby it's cold outside, so why don't we tuck into a curry?

by David Westbrook

It's the time of the year for caroling, and that means everyone's favorite The Twelve Days of Christmas. Being a cumulative song, we'd like a shortcut for constructing each verse, which boils down to a function (lines 3-8) that simply generates the form:

On the ? day of Christmas my true love gave to me
        and a partridge in a pear tree.

Sub::Curry will allow us to call that function for the current verse (line 12), and then create a new function (line 13), which includes the prose to date, to use for the next verse.

The HOLE and BLACKHOLE curry-constants create a way to prepend our arguments to generate the correct order; alternatively1 we could curry($fn,$lyric) and have $fn just reverse @_ , but this way spices things up! Other tasty recipes can be found in the would actually be better for Sub::Curry::Cookbook.

So, putting everything together, we can eat sing along with the last verse as generated:

On the twelfth day of Christmas my true love gave to me
        twelve drummers drumming,
        eleven pipers piping,
           ten lords a-leaping,
          nine ladies dacing,
         eight maids a-milking,
         seven swans a-swimming,
           six geese a-laying,
          five golden rings,
          four calling birds,
         three french hens,
           two turtle doves,
        and a partridge in a pear tree.

   1 use Sub::Curry qw/ :CONST curry /;
   3 my $fn = sub {
   4   my @lines = map { "\t" . $_ } @_;
   5   my @nums = qw/ first second third fourth fifth sixth seventh eighth nineth tenth eleventh twelfth /;
   6   $lines[-1] =~ s/\t\s*/\tand / if @lines > 1; # grammatical hack
   7   print "On the " . $nums[$#lines] . " day of Christmas my true love gave to me\n", join(",\n", @lines) . ".\n\n";
   8 };
  10 while( my $lyric = <DATA> ){
  11   chomp($lyric);
  12   $fn->($lyric);
  13   $fn = curry( $fn, HOLE, BLACKHOLE, $lyric );
  14 };
  16 __DATA__
  17      a partridge in a pear tree
  18    two turtle doves
  19  three french hens
  20   four calling birds
  21   five golden rings
  22    six geese a-laying
  23  seven swans a-swimming
  24  eight maids a-milking
  25   nine ladies dacing
  26    ten lords a-leaping
  27 eleven pipers piping
  28 twelve drummers drumming

1. Of course, simple loop/array solutions work as well; but TMTOWTDI and fun/holiday cheer is as a good reason as any!

Our resident discordian editor offers alternative lyrics.

View Source (POD)