Reputation: 263
Suppose I have three perl modules as given below :
Test.pm
package Test;
use strict;
use warnings;
use Check;
our $data = Check->getX;
1;
Initialize.pm
package Initialize;
use Check;
use Test;
Check->setX(10);
our $t = $Test::data;
print $t;
1;
Check.pm
package Check;
my $x = 12;
sub setX {
my ($self,$value) = @_;
$x = $value;
}
sub getX
{
return $x;
}
1;
Now, when I run Initialize.pm, I am initializing $x in Check.pm to 10 and $x is assigned to $data in Test.pm. But the the actual valuethat is assigned to $data is 12 which is the initial value given in Check.pm.
So, When are the global variables initialized in perl? How can I enforce that the new value set by me in the Initialize.pm to x is what is loaded into $data?
Now if I replace the statement use Test in Initalize.pm with require Test; and move the statement Check->setX(10) before this require statement then $data is correctly initialized to the new value 10. What is it that is happening differently in this case ?
Upvotes: 1
Views: 109
Reputation: 126722
In general modules have little or no executable code. Object-oriented modules just define the object methods, and sometimes some class data.
When you use Test
the whole of Test.pm
is compiled and executed, so the value of $data
is set at this point.
The call to setX
happens straight afterwards, but is too late to affect the asignment of $data
.
As I said in my comment your code has a very odd structure, and modules shouldn't have a time dependency on each other at all. You should really remove all executable statements from your modules, but to force your code to do what you want you can write
use strict;
use warnings;
use Check;
BEGIN {
Check->setX(10);
}
use Test;
our $t = $Test::data;
print $t;
But don't do that!
Upvotes: 1
Reputation: 5348
Perl executes a use statement prior to executing anything else in the file. So the execution order is:
use Check;
$x = 12;
use Test;
use Check;
-This only does importing as the file is already executed$data = Check->getX();
Check->setX(10);
If you replace use
with require
the instruction is evaluated at the same time as the rest of the instructions and if you move Check->setX(10);
before the require it will be evaluated before the get in Test
Upvotes: 1