6

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?

2 Answers 2

10

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I suspect that confusing package scope with lexical scope is an easy mistake to make; I know I've done it before.
There's not really a package scope. There's just the package keyword that changes the default package.
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.