Reputation: 59
I know how to use a variable from one package to another in Perl. I am trying to use a global variable declared in test1.pl
in another Perl script test2.pl
. I am using require
to load the perl file.
#!usr/bin/perl #test1.pl
use strict;
use warnings;
out $db_name; #global variable to be used in another script
fun();
sub fun
{
$db_name = 'xxyy';
}
#!usr/bin/perl #test2.pl
require 'test1.pl'; #require is used to include the perl script like we use "use" for importing packages
my $database = $db_name; #global variable from previous script
use strict;
use warnings;
testing();
sub testing
{
print "$database\n";
}
Upvotes: 3
Views: 8734
Reputation: 69224
This is all far easier if you create a "real" module. Requiring libraries like that was a Perl 4 trick.
In DBName.pm
, you have:
package DBName;
use strict;
use warnings;
use base 'Exporter';
our $DBName = 'xxyz';
our @EXPORT = qw[$DBName];
1;
And in the calling program:
#!/usr/bin/perl
use feature 'say';
use strict;
use warnings;
use DBName;
sub testing {
say $DBName;
}
testing();
But note that this only works if your Perl module is in one of the standard locations known to Perl via the @INC
array. If you just want to use a local file you'll have to add the directory your script and module live in before your use
instructions. Perl supplies the lib
pragma for this:
use File::Basename;
use lib dirname(__FILE__);
# the rest of your script here
Upvotes: 10
Reputation: 54323
You need to declare the variables with our
in both scripts.
# test1.pl
use strict;
use warnings;
our ( $foo );
$foo = 'bar';
# test2.pl
use strict;
use warnings;
our ( $foo );
require 'test1.pl';
print $foo; # bar
Your script test2.pl
starts out in the main
package because there is no package
declaration. When you require
a script that has no package
in it, all the code will be loaded at the point where the require
statement is. It will end up in the same package as the require
line. So what's in test1.pl
also ends up in the main
package of the same Perl instance.
our
declares a package variable. That means it's available as $foo
inside of your package, and it's visible outside. And that is the trick here.
Stuff that is declared with my $bar
inside of the script1.pl
will end up in its own scope when the file is required, so the outer scope script2.pl
cannot see that variable. But if you make it a package variable, it will be put into the package namespace, which is bigger.
We declare the package variable our $foo
first, and then require 'test1.pl'
. Inside of the other script, we do our $foo
again, so there is no $foo
used only once warning. The value of 'bar'
will end up in the package $foo
(which is actually $main::foo
, or $::foo
if you ommit the name of the package. From there, it will be accessed later when printing $foo
.
The order of the our
and require
doesn't really matter. But if you use globals, it makes sense to stick to some conventions, like listing all the global variables at the top of the script.
A word of advice: while this stuff seems to be easy, it is pretty outdated. Of course it works for small things, but it is hard to maintain. Only use this stuff in legacy applications if it's already there and rewriting is too costly. You know about packages already. Use them instead!
Upvotes: 6