our
在当前词法作用域内创建对当前包中同名包(即全局)变量的词法别名。
our
与 my
或 state
具有相同的词法作用域规则,这意味着它仅在词法作用域内有效。与 my
和 state
不同,它们都声明新的(词法)变量,our
仅创建对现有变量的别名:同名包变量。
这意味着当 use strict 'vars'
生效时,our
允许您使用包变量,而无需使用包名限定它,但仅限于 our
声明的词法作用域内。这立即生效 - 即使在同一语句中。
package Foo;
use v5.36; # which implies "use strict;"
$Foo::foo = 23;
{
our $foo; # alias to $Foo::foo
print $foo; # prints 23
}
print $Foo::foo; # prints 23
print $foo; # ERROR: requires explicit package name
即使包变量以前从未使用过,这也适用,因为包变量在第一次使用时就会出现。
package Foo;
use v5.36;
our $foo = 23; # just like $Foo::foo = 23
print $Foo::foo; # prints 23
因为变量在use strict 'vars'
下会立即合法,只要没有同名变量已经在作用域内,你就可以在同一个语句中再次引用包变量。
package Foo;
use v5.36;
my $foo = $foo; # error, undeclared $foo on right-hand side
our $foo = $foo; # no errors
如果列出了多个变量,则必须将列表放在括号中。
our($bar, $baz);
一个our
声明声明了一个包变量的别名,该别名将在其整个词法作用域内可见,甚至跨越包边界。变量被输入的包是在声明时确定的,而不是在使用时确定的。这意味着以下行为成立
package Foo;
our $bar; # declares $Foo::bar for rest of lexical scope
$bar = 20;
package Bar;
print $bar; # prints 20, as it refers to $Foo::bar
在同一个词法作用域内,如果多个our
声明具有相同的名称,则允许它们位于不同的包中。如果它们恰好位于同一个包中,并且你要求它们,Perl 会发出警告,就像多个my
声明一样。与第二个my
声明不同,第二个my
声明会将名称绑定到一个新的变量,而第二个our
声明在同一个包中,在同一个作用域中,仅仅是多余的。
use warnings;
package Foo;
our $bar; # declares $Foo::bar for rest of lexical scope
$bar = 20;
package Bar;
our $bar = 30; # declares $Bar::bar for rest of lexical scope
print $bar; # prints 30
our $bar; # emits warning but has no other effect
print $bar; # still prints 30
一个our
声明也可以有一系列与之相关的属性。
TYPE 和 ATTRS 的确切语义和接口仍在不断发展。TYPE 目前绑定到fields pragma 的使用,属性使用attributes pragma 处理,或者从 Perl 5.8.0 开始,也通过Attribute::Handlers 模块处理。有关详细信息,请参阅"perlsub 中的私有变量 via my()"。
请注意,对于带括号的列表,undef
可以用作虚拟占位符,例如跳过初始值的赋值
our ( undef, $min, $hour ) = localtime;