What is the most efficient way to export all constants (Readonly variables) from Perl module
Asked Answered
L

3

9

I am looking the most efficient and readable way to export all constants from my separate module,that is used only for storing constants.
For instance

use strict;
use warnings;

use Readonly;

Readonly our $MY_CONSTANT1         => 'constant1';
Readonly our $MY_CONSTANT2    => 'constant2'; 
....
Readonly our $MY_CONSTANT20    => 'constant20';

So I have a lot of variables, and to list them all inside our @EXPORT = qw( MY_CONSTANT1.... );
It will be painful. Is there any elegant way to export all constants, in my case Readonly variables(force export all ,without using @EXPORT_OK).

Lite answered 6/8, 2015 at 17:49 Comment(0)
D
5

Actual constants:

use constant qw( );
use Exporter qw( import );    

our @EXPORT_OK;

my %constants = (
   MY_CONSTANT1 => 'constant1',
   MY_CONSTANT2 => 'constant2',
   ...
);

push @EXPORT_OK, keys(%constants);
constant->import(\%constants);

Variables made read-only with Readonly:

use Exporter qw( import );
use Readonly qw( Readonly );

our @EXPORT_OK;

my %constants = (
   MY_CONSTANT1 => 'constant1',
   MY_CONSTANT2 => 'constant2',
   #...
);

for my $name (keys(%constants)) {
   push @EXPORT_OK, '$'.$name;
   no strict 'refs';
   no warnings 'once';
   Readonly($$name, $constants{$name});
}
Dysteleology answered 6/8, 2015 at 18:28 Comment(1)
Thanks for answer can you provide an example of using constants in both cases ?Lite
H
5

If these are constants which may need to to be interpolated into strings etc, consider grouping related constants into a hash, and making the hash constant using Const::Fast. This reduces namespace pollution, allows you to inspect all constants in a specific group etc. For example, consider the READYSTATE enumeration values for IE's ReadyState property. Instead of creating a separate variable, or separate constant function for each value, you could group them in a hash:

package My::Enum;

use strict;
use warnings;

use Exporter qw( import );
our @EXPORT_OK = qw( %READYSTATE );

use Const::Fast;

const our %READYSTATE => (
    UNINITIALIZED => 0,
    LOADING => 1,
    LOADED => 2,
    INTERACTIVE => 3,
    COMPLETE => 4,
);

__PACKAGE__;
__END__

And, then, you can intuitively use them as in:

use strict;
use warnings;

use My::Enum qw( %READYSTATE );

for my $state (sort { $READYSTATE{$a} <=> $READYSTATE{$b} } keys %READYSTATE) {
    print "READYSTATE_$state is $READYSTATE{$state}\n";
}

See also Neil Bowers' excellent review on 'CPAN modules for defining constants'.

Hemato answered 6/8, 2015 at 20:14 Comment(0)
C
0

In reply to @CROSP, you can use @ikegami's Readonly approach like this:

In MyConstants.pm

package MyConstants;
<code from answer above>
1;

Then in foo.pl

use MyConstants qw($MY_CONSTANT1, $MY_CONSTANT2);
print "This is $MY_CONSTANT1\n";
Clinkerbuilt answered 4/9, 2020 at 15:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.