http://www.perlmonks.org?node_id=202113

I was starting to write a constants module (and hating it) when the following funkiness sprang to mind.
This seems nicer to me than the standard way because I don't have to keep track of them in two places (in the constants pragma *and* the export list).
You can also do something like the second one if you really want to go all out.
Update: This only works with 5.8.0. 5.6.1 + earlier don't support creating multiple constants with a single use statement:(
package foo; use base qw( Exporter ); my %constants; use constant +{ %constants = ( AAA => 1, BBB => 2, CCC => 3, DDD => 4, ) }; our @EXPORT = keys %constants; 1; package foo2; use base qw( Exporter ); my %all; my %foo; my %bar; use constant +{ %all = ( %foo = ( AAA => 1, BBB => 2, ), %bar = ( CCC => 3, DDD => 4, ), ) }; our @EXPORT_OK = keys %all; our %EXPORT_TAGS = ( all => [ keys %all ], foo => [ keys %foo ], bar => [ keys %bar ], ); 1;

Replies are listed 'Best First'.
•Re: Creating constants modules
by merlyn (Sage) on Oct 02, 2002 at 04:36 UTC
    I've coded a slightly simpler variant of that:
    package MY::Constants; my %constants = ( FRED => 2, DINO => 4, WILMA => "bb-b-b-b-uck!", LARGE => 1e38, ); sub import { for (@_) { unless (exists $constants{$_}) { require Carp; Carp::croak("Constant $_ invalid"); } { no strict 'refs'; my $full_name = caller()."::$_"; my $value = $constants{$_}; # for closure *$full_name = sub () { $value }; } } } '0 but true';
    Unfortunately, you lose the default import list and the other nice things with Exporter, but for quick stuff, it's nice to say:
    use MY::Constants qw(FRED WILMA);

    -- Randal L. Schwartz, Perl hacker

      I've been implementing the same thing - module which consists all project contstants. Your code is good but I'd like to make small addition. I guess we should shift package name from @_ because it's passed as first parameter:

      package MY::Constants; my %constants = ( FRED => 2, DINO => 4, WILMA => "bb-b-b-b-uck!", LARGE => 1e38, ); sub import { my $package = shift; for (@_) { unless (exists $constants{$_}) { require Carp; Carp::croak("Constant $_ invalid"); } { no strict 'refs'; my $full_name = caller()."::$_"; my $value = $constants{$_}; # for closure *$full_name = sub () { $value }; } } } '0 but true';

      ~ Schiller