snaggs
snaggs

Reputation: 5713

How to import all variables from other package?

I have package with globals:

package Constants;

use strict;
use warnings;    

use Exporter qw( import );
use Exporter ();
use vars qw(@ISA @EXPORT_OK);
@ISA       = qw(Exporter);
@EXPORT_OK = qw(@A %B, $C, foo);

our %B = (id  => 0, desc => "AF :: BUILD SUCCEEDED");        
our @A = (
    "Undefined symbols for architecture",
    "BUILD FAILED"
);
our  $C = "blablabla";

sub foo(){}

1;

in other Perl file I can use this package as:

use FindBin qw($RealBin);
use lib $RealBin;    

use Constants qw(@A %B, $C, foo); 

It will work.

I want to change a bit the package usage like:

use Constants;

So logically the usage should be:

Constants::@A;  # I get an error
Constants::%B;  # I get an error
Constants::$C;  # I get an error

This approach works with methods, for example:

Constants::foo(); # works!!

So how I can use @A %B $C without calling chain them into qw(@A %B $C)?

Upvotes: 0

Views: 190

Answers (2)

Tony O'Quinn
Tony O'Quinn

Reputation: 1

package Constants;

use strict;

use warnings;

use Exporter;

our @ISA        = qw(Exporter);

our @EXPORT     = qw(@A %B $C foo); # always exports these to main::

our %B = (id  => 0, desc => "AF :: BUILD SUCCEEDED");

our @A = (

    "Undefined symbols for architecture",

    "BUILD FAILED"

);

our  $C = "blablabla";

sub foo(){}

1;

Upvotes: -2

simbabque
simbabque

Reputation: 54323

The sigil ($, @ or %) needs to go first when using fully qualified variable names.

@Constants::A; 
%Constants::B; 
$Constants::C; 

This is explained in the first parts of perlsyn.

You might have seen that in other packages, like Data::Dumper, which allows you to configure it with its package variables.

use Data::Dumper;
$Data::Dumper::Indent = 0;

In your package you can use $C, which simply has an empty namespace, so the current one is assumed.

$           foo  # namespace is nothing
$Constants::foo  # namespace is Constants::

It works with functions (what you're showing is not a method because there is no OOP involved, a method call would be Constants->foo) because those usually have no sigil. You could do &Constants::foo(), which uses the & to turn off any prototypes, but please don't do that unless you know what you're doing.

There is one more sigil * for typeglobs. The same rules apply for it.


The last sentence of your question is confusing.

[...] without calling chain them into qw(@A %B $C)?

I think you mean importing them. That's what the Exporter lets you do when you put the names into @EXPORT_OK. The list of names you pass to use Constants tells Exporter which symbols it should install into your namespace.

It then puts something like a pointer into your namespace that says your $C refers to the same thing as $Constants::C.

When you declare package variables with our or use vars (let's consider them equivalent for the scope of this answer), they are always accessible from the outside. You just need to use the fully qualified package name.

Importing them into your own namespace is just a convenience. You could do it yourself too.

use Constants (); # the empty list explicitly imports nothing
*C = \$Constants::C;

You just made your own import. But you probably don't want to do that.

Upvotes: 4

Related Questions