Why does a variable in Perl not respect a `package` statement?
Asked Answered
T

2

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?

Tourer answered 29/12, 2022 at 16:57 Comment(0)
S
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.

Sellars answered 29/12, 2022 at 17:23 Comment(2)
I suspect that confusing package scope with lexical scope is an easy mistake to make; I know I've done it before.Sellars
There's not really a package scope. There's just the package keyword that changes the default package.Greenling
C
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.

Chic answered 30/12, 2022 at 4:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.