Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Clean way to export all constants at once

by perl_help26 (Beadle)
on Jan 30, 2014 at 15:31 UTC ( #1072691=perlquestion: print w/replies, xml ) Need Help??
perl_help26 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I would like to export constants from a file The traditional way to export them is:

package global_constants; use strict; use warnings; use base 'Exporter'; use constant LOAD_ARABIC=>1; use constant LOG_USERS_ACTIONS=>1; use constant ENABLE_RCSE=>; our @EXPORT_OK = ('LOAD_ARABIC','LOG_USERS_ACTIONS','ENABLE_RCSE'); 1;

And in the perl file

use global_constants('LOAD_ARABIC' , 'LOG_USERS_ACTIONS','ENABLE_RCSE');

Is it possible to export everything at once (i.e. without listing the names of the constants in the export of both files?? I have so many constants and i need a neater way to export (preferably without any module) Thanks :))

Replies are listed 'Best First'.
Re: Clean way to export all constants at once
by toolic (Bishop) on Jan 30, 2014 at 15:48 UTC

      Thank you for the fast reply :D ... I realize that i still have to list the constants once in or else it gives me an error


      This is great but can I push it further so that I wouldn't have to list even in Thanks a lot.

        Instead of using the constant pragma, I'd use the Readonly module and create a readonly hash which is exported.

        You could even take it a step further and define individual lexical scalars in your module and export a readonly dispatch table of anonymous subs that return the individual scalar values.

        You may also want to read this review of 21 different modules that can be used to define constants.

        You might be able to use Readonly to built up a list of constant names.
Re: Clean way to export all constants at once
by tobyink (Abbot) on Jan 30, 2014 at 20:53 UTC
    package global_constants; use strict; use warnings; my %constants; BEGIN { %constants = ( LOAD_ARABIC => 1, LOG_USERS_ACTIONS => 1, ENABLE_RCSE => 1, ); } use constant \%constants; use base 'Exporter'; our @EXPORT = (); our @EXPORT_OK = keys(%constants); our %EXPORT_TAGS = ( all => \@EXPORT_OK, default => \@EXPORT, log => [ grep /^LOG_/, @EXPORT_OK ], # all constants beginning +with "LOG_" ); 1;

    And then in a module that uses it:

    use global_constants qw( :all );

    Another module that only needs to import the LOG_* constants, and one other one:

    use global_constants qw( :log ENABLE_RCSE );
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

      This is just PERFECT! Thank you... :D

Re: Clean way to export all constants at once
by boftx (Deacon) on Jan 31, 2014 at 01:53 UTC

    Many, many moons ago (this version is from 2006, having evolved from around 2001) I had reason to deal with this problem and this was what I wound up with after a while. It's pretty ugly by today's standards, but I think the principles might still be informative. (Although this version read its config values from a database, the original stored them in a hash.) Of particular interest is how the accessors for each config param are generated on the fly.

    On a side note, I was toying with inside-out objects for this since I didn't want people messing with config params other than by setting them via the UI.

    package Nortx::Config; use strict; =head1 NAME Nortx::Config - Nortx package configuration =head1 SYSNOPSYS use Nortx::Config; my $cfg = new Nortx::Config; my $plist = $cfg->params; my @plist = $cfg->params; my $base = $cfg->basedir; =head1 DECRIPTION This module provides a standard location to store constant data such a +s directory names, passwords and such. Unlike other objects in the Nortx system, this one is implemented as a reference to an anonymous scalar. None of the values returned by the accessors are stored in the object itself. Instead, the values ar +e stored in hashes private to the module itself. All accessors are READ-ONLY. Use the methods below to get a list of available accessors or read the source for more details. =cut use Carp; use Nortx::Db; # Start package block { my $pkg = __PACKAGE__; my $stdcfg = {}; sub _load { my $dbh = Nortx::Db->connect; # Get the values from the database my $dbparams = $dbh->selectall_hashref('select * from ntcadmin', 'param'); # Now make a local copy so we can release the DBI ram. foreach my $pname (keys(%{$dbparams})) { foreach (keys(%{$dbparams->{$pname}})) { $stdcfg->{$pname}->{$_} = $dbparams->{$pname}->{$_}; } } # and gen the accessors foreach my $attr (keys(%{$stdcfg})) { next if $pkg->can($attr); no strict 'refs'; *{"$pkg\::$attr"} = sub { my $self = shift; return $stdcfg->{$attr}->{value}; }; } } =head1 METHODS =head2 new Returns a reference to a C<Nortx::Config> object. =cut sub new { my $proto = shift; # we really don't care what the proto is in this case, but we' +ll keep it # handy if we want to do some defensive programming later. $pkg->_load; return (bless *foo{SCALAR}, $pkg); } =head2 params Can be called as either a CLass or Instance Method. Returns a list of available standard configuration variable names. # get list as an array my @plist = $cfg->params; # get list as a reference to an array my $plist = $cfg->params; =cut sub params { my $self = shift; my @pnames = keys(%{$stdcfg}); return (wantarray ? @pnames : \@pnames); } sub get_param { my $self = shift; my $pname = shift; croak("Must supply a param name to get\n") unless $pname; my $retval; eval { my $accessor = $pname; $retval = $self->$pname; }; if ($@) { croak($@); } return ($retval); } }; # end package block 1; __END__
    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Clean way to export all constants at once
by CountZero (Bishop) on Jan 30, 2014 at 22:41 UTC
    What do you think of this?

    The file with the constants:

    use Readonly; Readonly $test1 => 'EEN'; Readonly $test2 => 'TWEE'; Readonly $test3 => 'DRIE'
    And the file using these constants.
    use strict; do ''; print "$main::test1 $main::test2 $main::test3"; $main::test1 = 1;
    If you don't mind not using the strict pragma, you can drop the $main:: on the imported constants.


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1072691]
Approved by marto
Front-paged by toolic
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2017-06-29 05:02 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (653 votes). Check out past polls.