Wondering what you use for constants in your modules.  I want to have a
separate constants package that contains all my constants in one place that
other modules in a related set of modules can use/import as needed.

I know PBP recommends Readonly, and in the past I've tended toward "use
constant" because of the supposed in-lining of the constant scalars (which I
suspect isn't that critical considering how infrequent the constants are
likely used in, say, a web app in a single request).

But, I have also created a MyApp::Constants module where I defined a nested
hash of all my constants:

my %contants_map => (

     foo_status => {
           FOO_STATUS_ACTIVE => 1,
           FOO_STATUS_INACTIVE => 0,
     },

     user_role => {
            ROLE_ADMIN => 1,
            ROLE_USER => 2,
     },
);

And so on.  And then have an import method that exports the sets of
constants requested.  I'm not entirely clear if these functions are inlined
or not when done this way.  Seems like they might be candidates, if read
perlsub correctly.

What's you opinion about how best to use constants?


FWIW, I have not looked at this code in a while, but here's what I see in
one of my existing constant modules that allow exporting the individual
constants or sets of constants.



# Flatten constants_map
# Can't have duplicate names because they are flattened.  Could relax this
# requirement and only throw an error if two are imported, but having
# the same constant name mean two different things is trouble.


my %by_name;

for my $group_name ( keys %constants_map ) {
    for my $const ( keys %{ $constants_map{$group_name} } ) {
        croak "Constant $const name already used" if exists
$by_name{$const};
        $by_name{$const} = $constants_map{$group_name}{$const};
    }
}


sub import {
    my ( $self, @export ) = @_;

    my $caller_pkg = caller || die 'no caller';

    no strict 'refs';    ## no critic

    for my $name ( @export ) {
        if ( $name =~ s/^:// ) {

            # Valid name provided?
            my $group = $constants_map{$name} || carp "Constant group
':$name' not found";

            # Lets provide the hash directly.
            my $group_name = $caller_pkg . '::' . uc( $name );
            *{$group_name} = sub() { return %{$group} };


            # Export constants.
            for my $const ( keys %{$group} ) {
                my $sub_name = $caller_pkg . '::' . $const;
                *{$sub_name} = sub() { $group->{$const} };
            }
        }

        else {
            croak "Constant '$name' not found" unless exists
$by_name{$name};
            my $sub_name = $caller_pkg . '::' . $name;
            *{$sub_name} = sub() { $by_name{$name} };
        }
    } ## end for my $name ( @export )

    return;

} ## end sub import


-- 
Bill Moseley
mose...@hank.org

Reply via email to