Is there a clean way to export all constants from a module?

S

Steve Allan

I'm creating a module for the sole purpose of defining constants to be
shared among several Perl scripts. I'm looking for a way to simplify
getting all the constant names into the @EXPORT_OK array, so I don't
end up with this:

@EXPORT_OK = qw(CURRENTCHANGE BLDNUM STAGEROOTDIR ...);

because I can envision that list becoming large, and everytime I
define a new constant I have to remember to add it to the list.


Here's what I've tried:

Since the 'constant' pragma will accept a hash reference, I thought I
could define a hash, pass it's reference to constant and it's keys to
EXPORT_OK:


my %build_properties = (
CURRENTCHANGE => 'currentChange',
BLDNUM => 'buildNumber',
STAGEROOTDIR => 'stageRootDir',
WEBREPORTDIR => 'webReportDir',
);

use constant \%build_properties;
@EXPORT_OK = (keys %build_properties);

That produces this error from the calling script:

Undefined subroutine &Constants::CURRENTCHANGE called ...

Changing the export to this:
@EXPORT_OK = qw(CURRENTCHANGE BLDNUM WEBREPORTDIR STAGEROOTDIR);

produced the same error.

The conventional way

@EXPORT_OK = qw(CURRENTCHANGE BLDNUM WEBREPORTDIR STAGEROOTDIR);
use constant {
CURRENTCHANGE => 'currentChange',
BLDNUM => 'buildNumber',
STAGEROOTDIR => 'stageRootDir',
WEBREPORTDIR => 'webReportDir',
};

works, so all seems fine with the calling script. The problem *seems*
to be that

use constant \%build_properties

is not having the desired effect.

So, my questions are

1. Is there something wrong with 'use constant \%hash' ?

2. Is what I'm attempting to do bad Perl style?

3. If not 2, is there a preferred way to do this?


Thanks.
 
J

Jay Tilton

: Since the 'constant' pragma will accept a hash reference, I thought I
: could define a hash, pass it's reference to constant and it's keys to
: EXPORT_OK:

That will work perfectly.

The hangup is whether the hash really is defined before
you "use constant ...".

: my %build_properties = (
: CURRENTCHANGE => 'currentChange',
: BLDNUM => 'buildNumber',
: STAGEROOTDIR => 'stageRootDir',
: WEBREPORTDIR => 'webReportDir',
: );
:
: use constant \%build_properties;
: @EXPORT_OK = (keys %build_properties);

The assignment to %build_properties happens at run-time, but
"use constant \%build_properties;" happens at compile time.
Put the assignment in a BEGIN{} block so it too happens during
compilation.

my %build_properties;
BEGIN{
%build_properties = (
CURRENTCHANGE => 'currentChange',
BLDNUM => 'buildNumber',
STAGEROOTDIR => 'stageRootDir',
WEBREPORTDIR => 'webReportDir',
);
}
use constant \%build_properties;
@EXPORT_OK = (keys %build_properties);
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Steve Allan said:
I'm creating a module for the sole purpose of defining constants to be
shared among several Perl scripts. I'm looking for a way to simplify
getting all the constant names into the @EXPORT_OK array...

You might want to try my experimental Config::Vars module, which is
designed for what you have in mind -- although it doesn't support
constants, it does support Readonly variables.

Perhaps I should add support for constants to the module.

- --
Eric
$_ = reverse sort qw p ekca lre Js reh ts
p, $/.r, map $_.$", qw e p h tona e; print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBPyK+bGPeouIeTNHoEQKiXwCeMip86vOW5KiY1Y/KsxLKSzOF3e0An2We
HzYie+2TflIaQTSiNs5xajOK
=xegT
-----END PGP SIGNATURE-----
 
S

Steve Allan

The assignment to %build_properties happens at run-time, but
"use constant \%build_properties;" happens at compile time.
Put the assignment in a BEGIN{} block so it too happens during
compilation.

my %build_properties;
BEGIN{
%build_properties = (
CURRENTCHANGE => 'currentChange',
BLDNUM => 'buildNumber',
STAGEROOTDIR => 'stageRootDir',
WEBREPORTDIR => 'webReportDir',
);
}
use constant \%build_properties;
@EXPORT_OK = (keys %build_properties);

Works like a charm - Thanks!
 
B

Bart Lateur

Steve said:
I'm creating a module for the sole purpose of defining constants to be
shared among several Perl scripts. I'm looking for a way to simplify
getting all the constant names into the @EXPORT_OK array, so I don't
end up with this:

@EXPORT_OK = qw(CURRENTCHANGE BLDNUM STAGEROOTDIR ...);

because I can envision that list becoming large, and everytime I
define a new constant I have to remember to add it to the list.

That's not your only problem. Every script using this module will also
have to be changed to include this constant in it's use statement. Or is
that not a problem? If you don't use a constant, you don't need to
import it...

But anyway: there's a way to group these names into a tag, for example
":constants", and all you have to do to import them all, is call

use Foo qw:)constants);

For this to happen, you have to include the tag and it's associated
names in the variable %EXPORT_TAGS, not @EXPORT_OK, like this:

%EXPORT_TAGS = (
constants => [qw(CURRENTCHANGE BLDNUM STAGEROOTDIR)]
);

You can supply multiple tags, even including some of the same names more
than once, allowing for refinement on groups of constants.

See the documentation for Exporter for all the details.

You can use whatever method you used to fill @EXPORT_OK, to populate
this hash.
 
S

Steve Allan

Bart,

Bart Lateur said:
That's not your only problem. Every script using this module will also
have to be changed to include this constant in it's use statement. Or is
that not a problem? If you don't use a constant, you don't need to
import it...

But anyway: there's a way to group these names into a tag, for example
":constants", and all you have to do to import them all, is call

use Foo qw:)constants);

This works very nicely! By combining your suggestion with Jay's I have
exactly what I was after.

Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top