How do I change the value of a variable in the package used by a module so that subroutines in that module can use it?
Here’s my test case:
testmodule.pm:
package testmodule;
use strict;
use warnings;
require Exporter;
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
@ISA = qw(Exporter);
@EXPORT = qw(testsub);
my $greeting = "hello testmodule";
my $var2;
sub testsub {
printf "__PACKAGE__: %s\n", __PACKAGE__;
printf "\$main::greeting: %s\n", $main::greeting;
printf "\$greeting: %s\n", $greeting;
printf "\$testmodule::greeting: %s\n", $testmodule::greeting;
printf "\$var2: %s\n", $var2;
} # End testsub
1;
testscript.pl:
#!/usr/bin/perl -w
use strict;
use warnings;
use testmodule;
our $greeting = "hello main";
my $var2 = "my var2 in testscript";
$testmodule::greeting = "hello testmodule from testscript";
$testmodule::var2 = "hello var2 from testscript";
testsub();
output:
Name "testmodule::var2" used only once: possible typo at ./testscript.pl line 11.
__PACKAGE__: testmodule
$main::greeting: hello main
$greeting: hello testmodule
$testmodule::greeting: hello testmodule from testscript
Use of uninitialized value $var2 in printf at testmodule.pm line 20.
$var2:
I expected $greeting and $testmodule::greeting to be the same since the package of the subroutine is testmodule.
I guess this has something to do with the way used modules are evald as if in a BEGIN block, but I’d like to understand it better.
I was hoping to set the value of the variable from the main script and use it in the module’s subroutine without using the fully-qualified name of the variable.
After reading Variable Scoping in Perl: the basics more carefully, I realized that a variable declared with
myisn’t in the current package. For example, in a simple script with no modules if I declaremy $var = "hello"$main::varstill doesn’t have a value.The way that this applies in this case is in the module. Since
my $greetingis declared in the file, that hides the package’s version of$greetingand that’s the value which the subroutine sees. If I don’t declare the variable first, the subroutine would see the package variable, but it doesn’t get that far because Iuse strict.If I don’t
use strictand don’t declaremy $greeting, it works as I would have expected. Another way to get the intended value and not breakuse strictis to useour $greeting. The difference being that my declares a variable in the current scope while our declares a variable in the current package.