YA Perl Advent Calendar 2005-12-24

To atone for yesterday's delay, today I bring you two related modules: enum && enum::hash. enum provides the ability to create C-style enums i.e; a simple means of producing a series of english-named numeric constants1. The canonical example is to index into the myriad return values of array context localtime. enum::hash provides an interface styled after enum for creating a hash; in case you don't want a slew of contants cluttering your namespace, or wish to avoid a naming conflict. So while a $LC{year} from enum::hash is arguably more perlish than an enum LC_Year it's really a matter of personal preference.


   1 use enum qw(:LC_ Sec Min Hour MDay Mon Year WDay YDay IsDST);
   2 use enum qw(:Months_ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
   3 print "Happy New Year!!\n" if (localtime)[LC_Mon] == Months_Jan &&
   4   (localtime)[LC_MDay] == 1;
   6 use enum::hash 'enum';
   7 %LC    = enum qw(Sec Min Hour MDay Mon Year WDay YDay Isdst);
   8 %month = enum qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
   9 print "Happy New Year!!\n" if (localtime)[$LC{Mon}] == $month{Jan} &&
  10   (localtime)[$LC{MDay}] == 1;

In the BUGS section of enum's POD the author gripes

     No way (that I know of) to cause compile time errors when
     one of these enum names get redefined.  IMHO, there is
     absolutely no time when redefining a sub is a Good
     Thing[tm], and should be taken out of the language, or at
     least have a pragma that can cause it to be a compile time
Well, in the intervening 6 years a lot has happened... from perldiag:
     Constant subroutine %s redefined
         (S) You redefined a subroutine which had previously been
         eligible for inlining.  See "Constant Functions" in
         perlsub for commentary and workarounds.

1. Actually, they support enums to letter values–A..Z–however the actual utility of such is questionable.