I'm writing an app in Perl with several modules. I want to write some global constants that will be visible from everywhere, like this:
#Constants.pm
$h0 = 0;
$scale = 20;
And then use them without qualifying with main::
or Constants::
in several modules. However, if I write use Constants;
in more than one module, they only get imported into one namespace. Is there any way around this?
I'm using the latest ActivePerl.
Check out Exporter and the perlmod
man page.
This chunk of code should do exactly what you want. Send all kudos to lkundrak.
package Constants;
use base qw/Exporter/;
use constant BOB => 666;
use constant ALICE => 555;
sub import {
no strict "refs";
${[caller]->[0].'::'}{$_} = ${__PACKAGE__."::"}{$_}
foreach grep { not /^(ISA|isa|BEGIN|import|Dumper)$/ }
keys %{__PACKAGE__."::"};
}
Don't tell anyone I told you this, but Perl's special variables are available everywhere. You have probably noticed that this doesn't work:
{ package Foo;
our $global = 42; }
{ package Bar;
say "global is $global"; }
That's because $global
is actually called $Foo::global
. You've
also probably noticed that this "rule" doesn't apply to things like
@INC
, %ENV
, $_
, etc. That's because those variables are always
assumed to be in main
.
But actually, it's more than just those variables. The entire glob
gets "forced" into main
. That means you can write something like
this:
{ package Constants;
$_{PI} = 3.141592; }
{ package Foo;
say "pi is $_{PI}"; }
and it will work.
(The same applies for $ENV
, &INC
, etc.)
If you ever do this in real code, however, expect someone to murder you :) It is good to know, though, just in case you see someone else doing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With