Consider the following Perl code:
use strict;
use warnings;
use feature qw(say);
package A;
our $x = 1;
package B;
our $x = 2;
package A;
say $x;
package B;
say $x;
The output is:
2
2
However, I would have expected:
1
2
Why does $x
after package A
refer to $B::x
instead of $A::x
?
CodePudding user response:
Basically it's a scope thing.
From the documentation on our
:
An
our
declaration declares an alias for a package variable that will be visible across its entire lexical scope, even across package boundaries. The package in which the variable is entered is determined at the point of the declaration, not at the point of use.
The first our
creates makes $x
an alias for $A::x
. The second one reassigns $x
to be an alias for $B::x
, shadowing/replacing the previous one so that further uses of an unqualified $x
in the same lexical scope (the file in this case since it's outside a block) refers to the B
package variable no matter what the current package is.
This duplication of names is explicitly allowed per the docs:
Multiple
our
declarations with the same name in the same lexical scope are allowed if they are in different packages.
CodePudding user response:
our
creates lexically-scoped variable that is mapped to the similarly-named variable in the package in which the declaration is found.
package A;
our $x;
is equivalent to
package A;
use experimental qw( refalising declared_refs );
my \$x = \$A::x;
Subsequently changing the package has no effect.