Scoping

our#

Declare a lexically scoped alias to a package variable.

our does not create a new variable. It introduces a name into the current lexical scope that refers to the package variable of the same name in the current package. For the duration of that scope, the unqualified name is legal under use strict 'vars', and every read or write through it hits the underlying package variable.

If the package variable did not exist yet, our does not conjure it either — it simply names it. Package variables spring into existence when first assigned to, and an our declaration makes that first assignment possible without a fully qualified name.

Synopsis#

our $x;
our ($a, $b, $c);
our @EXPORT_OK = qw(foo bar);
our $VERSION : shared = '1.00';

What you get back#

our returns its list of variables, so it can appear in any expression position where my can:

(our $x, our $y) = (1, 2);
our $count = 0;

As a declaration it has no separate return value beyond that — the useful effect is the scoping side effect, not the value.

Scope and what the alias actually is#

The alias lives in the enclosing lexical block, just like my and state. It ends at the closing brace of that block (or the end of the file for a top-level declaration). Outside the scope, the unqualified name is no longer legal under use strict 'vars' — the package variable itself is untouched and still reachable by its fully qualified name.

package Foo;
use strict;

$Foo::foo = 23;

{
    our $foo;        # alias to $Foo::foo
    print $foo;      # 23
}

print $Foo::foo;     # 23 — the package variable is unaffected
print $foo;          # error: requires explicit package name

Because our aliases a package variable, the package is fixed at the point of declaration, not at the point of use. Changing packages with package mid-scope does not rebind the alias:

package Foo;
our $bar;            # declares $Foo::bar for the rest of this scope
$bar = 20;

package Bar;
print $bar;          # 20 — still refers to $Foo::bar

our vs my#

our and my look alike on the page and are constantly confused. They do opposite things.

  • my creates a fresh private variable that lives only inside its lexical scope. It has no name in any package’s symbol table and nothing outside the scope can reach it.

  • our creates a lexically scoped alias to a public package variable. The variable lives in the symbol table; any other code that knows its fully qualified name can read or write it.

Use my by default. Reach for our when you deliberately want package-global state: module exporter lists (our @EXPORT, our @EXPORT_OK), our $VERSION, a package-wide configuration hash other code is expected to poke at, or the traditional our @ISA for inheritance.

package My::Module;

our $VERSION   = '1.23';
our @EXPORT_OK = qw(frobnicate);
our @ISA       = ('Exporter');

Each of those names is an alias to $My::Module::VERSION, @My::Module::EXPORT_OK, @My::Module::ISA — exactly what Exporter and UNIVERSAL::isa go looking for.

our vs local#

local and our often appear together and are complementary, not alternatives.

  • our makes the package variable reachable under its unqualified name inside a lexical scope. It does not save or restore the value.

  • local saves a package variable’s current value and arranges for it to be restored when the enclosing dynamic scope ends. It does not make the name legal under use strict 'vars'.

The idiomatic pairing — temporarily change a package global inside a subroutine — uses both:

sub with_verbose {
    our $verbose;        # make the unqualified name legal here
    local $verbose = 1;  # save old value, restore on return
    do_work();
}

our vs state#

state is the other lexical declaration. It creates a private variable whose value persists across calls to the enclosing subroutine. our shares none of that machinery — its variable is public and has no per-call semantics. Pick state for per-subroutine memoisation, our for package-global state.

Scope of the declaration itself#

Like my, state, and local, our can appear anywhere an expression can (outside string interpolation). The declaration takes effect immediately — even within the same statement — so the variable satisfies use strict 'vars' from the declaration onward. But the declaration does not retroactively cover earlier uses of the same name in the same statement:

package main;
my $x = 2;
foo($x, our $x = $x + 1, $x);   # foo() receives (2, 3, 2)
foo($x, our $z = 5, $z);        # foo() receives (3, 5, 5)

The rule: each occurrence of the name is resolved as of its own position in the statement. After the declaration, the name is the alias; before it, the name means whatever it meant before.

The declaration also lets you reference the package variable on the right-hand side of its own initialiser, which is something my does not allow:

my  $foo = $foo;   # error under strict: undeclared $foo on RHS
our $foo = $foo;   # fine: RHS $foo is the package variable

Multiple variables and placeholders#

More than one variable requires parentheses:

our ($bar, $baz);

Inside a parenthesised list, undef is a valid placeholder that discards the corresponding value of a list assignment:

our ( undef, $min, $hour ) = localtime;

Repeated declarations#

Multiple our declarations with the same name in the same lexical scope are allowed when they are in different packages — each rebinds the alias to its package’s variable:

use warnings;

package Foo;
our $bar;            # declares $Foo::bar for the rest of this scope
$bar = 20;

package Bar;
our $bar = 30;       # declares $Bar::bar — aliases the Bar variable
print $bar;          # 30

A second our declaration for the same name in the same package and scope is merely redundant — it rebinds to the same variable. Under use warnings Perl reports it the way it reports a repeated my, but there is no fresh variable and nothing is shadowed:

use warnings;
package Bar;
our $bar = 30;
our $bar;            # warning, but still the same $Bar::bar
print $bar;          # 30

Attributes and TYPE#

our accepts the full declaration syntax of my:

our $x : shared;
our MyType $obj;
our $VERSION : shared = '1.00';

TYPE is currently bound to the fields pragma. Attributes are processed by the attributes pragma (and, since 5.8.0, by Attribute::Handlers). See the attributes pragma for the set of standard attributes. Ordinary user-level code rarely uses either.

Examples#

Module preamble — the overwhelmingly most common use:

package My::Thing;
use strict;
use warnings;

our $VERSION   = '0.01';
our @ISA       = ('Exporter');
our @EXPORT_OK = qw(thingify);

Declare and assign in one step:

package Cfg;
our $timeout = 30;   # same as $Cfg::timeout = 30

Temporarily override a package global inside a call:

sub quiet_run {
    our $verbose;
    local $verbose = 0;
    run_one_job();
}

Cross-package alias — declaration in Foo, use in Bar:

package Foo;
our $shared = 'hello';

package Bar;
# $shared here still refers to $Foo::shared, because the lexical
# alias was introduced while the current package was Foo.
print $shared;       # hello

Parenthesised list with placeholder:

our ( undef, $min, $hour, undef, $mon, $year ) = localtime;

Edge cases#

  • our does not create the variable. It declares an alias. The package variable exists the moment anything assigns to it (or takes a reference to it); our $x; alone does not allocate a new slot in the symbol table.

  • The alias is lexical, the variable is not. Leaving the scope of the our ends the alias, not the variable. Another scope in another file that declares our $x; in the same package sees the same storage.

  • Same-statement resolution. Only occurrences of the name after the our declaration in a statement use the alias. Earlier occurrences keep their prior binding (see the foo() example above).

  • Package, not current package at use. The alias is bound to the package in force at the point of declaration. Switching package later does not re-target it.

  • Not the same as use vars. use vars '$x' makes $x legal under strict for the rest of the package, regardless of scope. our $x is lexical. Prefer our; use vars is legacy.

  • Not a file-scoped pragma. A top-level our $x; in a file covers until the end of the file, which is a lexical scope — but require-ing that file from elsewhere does not extend the alias into the requiring file’s scope.

  • Attribute and TYPE semantics are still evolving. Anything beyond : shared in user code is rare; read the attributes and fields pragma documentation before relying on them.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • my — declare a private lexical variable; the default choice when you want a new variable

  • local — dynamically scope a temporary value for a package variable; pairs with our when you need both strict legality and save/restore

  • state — declare a private lexical variable that persists across calls to the enclosing subroutine

  • package — set the current package, which is what our aliases into

  • use — compile-time module loader; use strict 'vars' is the pragma that makes our necessary in the first place

  • undef — valid placeholder inside a parenthesised our list to discard a value on assignment