Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Constants across package boundaries

Reply
Thread Tools

Constants across package boundaries

 
 
bernie@fantasyfarm.com
Guest
Posts: n/a
 
      05-13-2008
I've been chasing a compile problem and I just saw the light on what
my trouble is: I use a bunch of "use constant this => ...; use
constant that =>...;" to set parameters for the program. BUT: the
program uses a 'package' or two [it has a small embedded objects in
it]. The trouble is that the package can't access the 'constant' --
that section of the program gets [not surprisingly] bareword errors.
I can fix them by using "main::..." but that's really ugly. Is there
any really clean way to set up truly "global" constants? Thanks!

/Bernie\
 
Reply With Quote
 
 
 
 
Joost Diepenmaat
Guest
Posts: n/a
 
      05-13-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> I've been chasing a compile problem and I just saw the light on what
> my trouble is: I use a bunch of "use constant this => ...; use
> constant that =>...;" to set parameters for the program. BUT: the
> program uses a 'package' or two [it has a small embedded objects in
> it]. The trouble is that the package can't access the 'constant' --
> that section of the program gets [not surprisingly] bareword errors.
> I can fix them by using "main::..." but that's really ugly. Is there
> any really clean way to set up truly "global" constants? Thanks!


I think you'd rather just export the constants to any package that
needs them, instead of making them truly global (which would be more
or less equivalent to exporting them to *all* packages)

See perldoc Exporter.



--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
 
Reply With Quote
 
 
 
 
bernie@fantasyfarm.com
Guest
Posts: n/a
 
      05-13-2008
On May 13, 9:02*am, Joost Diepenmaat <(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
> > I've been chasing a compile problem *and I just saw the light on what
> > my trouble is: I use a bunch of "use constant this => ...; use
> > constant that =>...;" to set parameters for the program. *BUT: the
> > program uses a 'package' or two [it has a small embedded objects in
> > it].


I note that this is documented on the 'constant' man page. Sigh. I
guess I could just use ::THIS and ::that but that feels a bit
inelegant...

> I think you'd rather just export the constants to any package that
> needs them, instead of making them truly global (which would be more
> or less equivalent to exporting them to *all* packages)


Can you export from main *to* a package? Using Exporter in this way
looks like it is a little confusing (it might become clearer after
another six readings of the man page..)). I guess I could do
something along the lines of putting require Exporter in my main
program, setting up @EXPORT_OK in the main program the "constants" I
want the interior packages to be able to import, and then do
a ::import(stuff I need) after the 'package' for the interior object-
section? You're right: that kind of approach would make the interior
packages be more self-contained and clearer (by making explicit that
they're pulling in those vbls from "main::")

OTOH, I see that there's a "Readonly" package that looks like it will
do what I was originally trying to do ["Readonly \my $CONST => val"
generates a real cross-package constant]. [although now that I see a
way to do what I originally wanted, I'm not so sure it is as clean a
way to go as I'd like...]

Thanks...

/Bernie\
 
Reply With Quote
 
bernie@fantasyfarm.com
Guest
Posts: n/a
 
      05-13-2008
On May 13, 9:50*am, (E-Mail Removed) wrote:
> On May 13, 9:02*am, Joost Diepenmaat <(E-Mail Removed)> wrote:


> > I think you'd rather just export the constants to any package that
> > needs them, instead of making them truly global (which would be more
> > or less equivalent to exporting them to *all* packages)


>... *I guess I could do
> something along the lines of putting require Exporter in my main
> program, setting up @EXPORT_OK in the main program the "constants" I
> want the interior packages to be able to import, and then do
> a ::import(stuff I need) after the 'package' for the interior object-
> section?


I'm running down this path to see how it looks and feels to properly
export and import my "global" constants. And I've run into a
problem. The man page for Exporter says:

package YourModule;
use Exporter 'import'; # gives you Exporter's import() method
directly
@EXPORT_OK = qw(munge frobnicate); # symbols to export on request

But in my code I have:
--------------------------
#!/usr/bin/perl

use strict ;
use warnings ;

use Exporter 'import' ;
our @ISA = qw(Exporter);
use constant AAA => 4 ;
our @EXPORT_OK = ('AAA') ;
----------------------------

"import" is not exported by the Exporter module at test.pl line 6

I can't figure out quite what I'm doing wrong... And then I'm
guessing that down in the program in my package I'd do:
package MYPACKAGE;
::import(qw(constants I want))

/Bernie\
 
Reply With Quote
 
Ted Zlatanov
Guest
Posts: n/a
 
      05-13-2008
On Tue, 13 May 2008 05:36:40 -0700 (PDT) (E-Mail Removed) wrote:

b> I've been chasing a compile problem and I just saw the light on what
b> my trouble is: I use a bunch of "use constant this => ...; use
b> constant that =>...;" to set parameters for the program. BUT: the
b> program uses a 'package' or two [it has a small embedded objects in
b> it]. The trouble is that the package can't access the 'constant' --
b> that section of the program gets [not surprisingly] bareword errors.
b> I can fix them by using "main::..." but that's really ugly. Is there
b> any really clean way to set up truly "global" constants? Thanks!

This may be possible with some advanced wizardry or source filtering.
You could also fake it like this:

#!/usr/bin/perl

use warnings;
use strict;

use constant GLOBAL => 'global';

package test;

use constant LOCAL => main::GLOBAL; # can also be called GLOBAL

print LOCAL, "\n";

but it's probably easiest if you set up a 'constants' package that
exports the right things, and import it into each package that needs it.

I'm sure there's better ways

Ted
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      05-13-2008

Quoth (E-Mail Removed):
> On May 13, 9:50*am, (E-Mail Removed) wrote:
> > On May 13, 9:02*am, Joost Diepenmaat <(E-Mail Removed)> wrote:

>
> > > I think you'd rather just export the constants to any package that
> > > needs them, instead of making them truly global (which would be more
> > > or less equivalent to exporting them to *all* packages)

>
> >... *I guess I could do
> > something along the lines of putting require Exporter in my main
> > program, setting up @EXPORT_OK in the main program the "constants" I
> > want the interior packages to be able to import, and then do
> > a ::import(stuff I need) after the 'package' for the interior object-
> > section?


It's probably a bad idea to export from main::. I'd define a separate
package for your constants, and 'use' it from everywhere else.

> I'm running down this path to see how it looks and feels to properly
> export and import my "global" constants. And I've run into a
> problem. The man page for Exporter says:
>
> package YourModule;
> use Exporter 'import'; # gives you Exporter's import() method
> directly
> @EXPORT_OK = qw(munge frobnicate); # symbols to export on request
>
> But in my code I have:
> --------------------------
> #!/usr/bin/perl
>
> use strict ;
> use warnings ;
>
> use Exporter 'import' ;
> our @ISA = qw(Exporter);
> use constant AAA => 4 ;
> our @EXPORT_OK = ('AAA') ;
> ----------------------------
>
> "import" is not exported by the Exporter module at test.pl line 6


Does the manpage you're using match your version of Exporter? The
ability to import (rather than inherit) Exporter::import was not present
in older versions of Exporter.

Ben

--
Although few may originate a policy, we are all able to judge it.
Pericles of Athens, c.430 B.C.
(E-Mail Removed)
 
Reply With Quote
 
Thomas Kratz
Guest
Posts: n/a
 
      05-13-2008
(E-Mail Removed) wrote:
> I've been chasing a compile problem and I just saw the light on what
> my trouble is: I use a bunch of "use constant this => ...; use
> constant that =>...;" to set parameters for the program. BUT: the
> program uses a 'package' or two [it has a small embedded objects in
> it]. The trouble is that the package can't access the 'constant' --
> that section of the program gets [not surprisingly] bareword errors.
> I can fix them by using "main::..." but that's really ugly. Is there
> any really clean way to set up truly "global" constants? Thanks!


Not clean nor elegant but works for simple (not array or hash) constants
by feeding the constants from main again to 'use constants':

test.pl:

use strict;
use warnings;
use constant BLA => 5;
use Mod;
print Mod::Sub1();

Mod.pm

package Mod;
use strict;
use warnings;

my %const;
BEGIN {
%const = map {
(my $name = $_) =~ s/^main:://;
no strict 'refs';
$name => &$_();
} grep {
/^main::/
} keys %constant::declared;
}

use constant \%const;

sub Sub1 { return BLA; }

1;

Thomas

--
$/=$,,$_=<DATA>,s,(.*),$1,see;__END__
s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
$_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
'%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e. r^.>l^..>k^.-
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      05-13-2008
(E-Mail Removed) wrote in news:85c5f60e-9834-43d0-8d8b-
(E-Mail Removed):

> I've been chasing a compile problem and I just saw the light on what
> my trouble is: I use a bunch of "use constant this => ...; use
> constant that =>...;" to set parameters for the program. BUT: the
> program uses a 'package' or two [it has a small embedded objects in
> it]. The trouble is that the package can't access the 'constant' --
> that section of the program gets [not surprisingly] bareword errors.
> I can fix them by using "main::..." but that's really ugly. Is there
> any really clean way to set up truly "global" constants? Thanks!


The proper way to do this would be to set up a package for all your
constants and use it from any file that needs any of those constants.

Keep in mind that constants defined using the constant pragma are not
variables but subroutines.

In any case, here is how to do it:

E:\Home\asu1\Src\Test> cat My\Constants.pm
package My::Constants;

use strict;
use warnings;

use base qw( Exporter );

our @EXPORT = qw();
our @EXPORT_OK = qw( ONE TWO THREE );

use constant ONE => 'one';
use constant TWO => 'two';
use constant THREE => 'three';

1;

E:\Home\asu1\Src\Test> cat My\Util.pm
package My::Util;

use strict;
use warnings;

use My::Constants qw( ONE TWO THREE );

sub some_func { join( "\t", ONE, TWO, THREE ) }

1;

E:\Home\asu1\Src\Test> cat C.pl
#!/usr/bin/perl

use strict;
use warnings;

use My::Constants qw( ONE TWO THREE );
use My::Util;

print "$_\n" for ONE, TWO, THREE, My::Util::some_func;

__END__

E:\Home\asu1\Src\Test> C
one
two
three
one two three


--
A. Sinan Unur <(E-Mail Removed)>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
Reply With Quote
 
Thomas Kratz
Guest
Posts: n/a
 
      05-13-2008
A. Sinan Unur wrote:

> package My::Constants;
>
> use strict;
> use warnings;
>
> use base qw( Exporter );
>
> our @EXPORT = qw();
> our @EXPORT_OK = qw( ONE TWO THREE );
>
> use constant ONE => 'one';
> use constant TWO => 'two';
> use constant THREE => 'three';
>
> 1;


I just needed that last week for a module but found the:

our @EXPORT_OK = qw( ONE TWO THREE );

a bit tedious when you are having many constants. I had to play around a
bit and found you can do (maybe that's obvious, but it wasn't to me):

my %constant_hash;
BEGIN {
%constant_hash = (
ONE => 'one',
TWO => 'two',
THREE => 'three',
};
}
our @EXPORT_OK = keys %constant_hash;
our %EXPORT_TAGS = (
constants => [keys %constant_hash],
);

Thomas

--
$/=$,,$_=<DATA>,s,(.*),$1,see;__END__
s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
$_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
'%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e. r^.>l^..>k^.-
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      05-13-2008

Quoth Thomas Kratz <(E-Mail Removed)>:
> A. Sinan Unur wrote:
>
> > package My::Constants;
> >
> > use strict;
> > use warnings;
> >
> > use base qw( Exporter );
> >
> > our @EXPORT = qw();
> > our @EXPORT_OK = qw( ONE TWO THREE );
> >
> > use constant ONE => 'one';
> > use constant TWO => 'two';
> > use constant THREE => 'three';
> >
> > 1;

>
> I just needed that last week for a module but found the:
>
> our @EXPORT_OK = qw( ONE TWO THREE );
>
> a bit tedious when you are having many constants. I had to play around a
> bit and found you can do (maybe that's obvious, but it wasn't to me):
>
> my %constant_hash;
> BEGIN {
> %constant_hash = (
> ONE => 'one',
> TWO => 'two',
> THREE => 'three',
> };
> }
> our @EXPORT_OK = keys %constant_hash;
> our %EXPORT_TAGS = (
> constants => [keys %constant_hash],
> );


There's no need for the BEGIN block: since this is a 'use'd module,
everything will happen at BEGIN time anyway.

require constant;

my %constants = (
ONE => 'one',
TWO => 'two',
);

our (@EXPORT_OK, %EXPORT_TAGS);

for (keys %constants) {
constant->import($_ => $constants{$_});
push @{ %EXPORT_TAGS{constants} }, $_;
}
push @EXPORT_OK, @{ %EXPORT_TAGS{constants} };

Ben

--
"Faith has you at a disadvantage, Buffy."
"'Cause I'm not crazy, or 'cause I don't kill people?"
"Both, actually."
[(E-Mail Removed)]
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Catching exceptions across shared object boundaries foxx C++ 4 08-31-2006 01:20 PM
Regexp help - Negative lookahead before across word boundaries Phrogz Ruby 2 02-19-2005 02:19 AM
Need Help Impersonating Across Process Boundaries hoochiegooch@hotmail.com ASP .Net 4 02-07-2005 04:40 PM
Credentials across multiple web service boundaries Bil Simser [MVP] ASP .Net Web Services 0 09-03-2004 11:23 PM
Using underscores as well as word boundaries to demarcate a pattern Laura Perl 1 06-03-2004 05:25 PM



Advertisments