Perl中的包变量不在"范围"中?

Dav*_* W. 2 perl perlvar

我正在看这个问题,当我在玩耍时,我遇到了这个问题:

#! /usr/bin/env perl
#
# use warnings;
use strict;
use feature qw(say);

{
    our $foo = "bar";
    say "Foo = $foo";
}

say "Foo = $foo";  # This is line #12
Run Code Online (Sandbox Code Playgroud)

是的,我确实use warnings;关掉了......

当我运行这个时,我得到:

Variable "$foo" is not imported at ./test.pl line 12.
Global symbol "$foo" requires explicit package name at ./test.pl line 12.
Execution of ./test.pl aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)

嗯...我得到相同的" 变量"$ foo"不会导入./test.pl第12行. "如果我已经完成错误my $foo = "bar";.我使用时会理解这一点,my因为$foo一旦离开块就没有变量.但是,our变量被认为是包范围.我能理解$foo那时可能没有价值,但是这个?

另外," 变量"$ foo"未在./test.pl第12行导入 "是什么意思?我理解包和导入,但这里只有一个包main.$foo应该在main包中.它不需要导入.

我的包变量发生了什么,它在超出范围后似乎不在包中?


附录

因此,如果您使用$::fooour $foo;再次创建另一个别名,您的程序将按预期工作.CMJ

我们来试试吧......

#! /usr/bin/env perl
#
# use warnings;
use strict;
use feature qw(say);

{
    our $foo = "bar";
    say "Foo = $foo";
}

our $foo;          # Redeclared
say "Foo = $foo";  # This is line #12
Run Code Online (Sandbox Code Playgroud)

现在,打印出来:

bar
bar
Run Code Online (Sandbox Code Playgroud)

正如所有回答的人所指出的,our只是对同名的包变量进行别名,并且它是词法范围的.这意味着一旦别名超出范围,所以没有我访问的价值的能力$main::foo$foo.这是我以前从未意识到的.

然而,正如cjm指出的那样,重新声明our $foo;恢复别名,并且已经存在$main::foo的别名将返回到新的别名$foo.当我重新声明our $foo;,价值$foo恢复.

这是关于our可能如此令人困惑的变量的事情之一.你看到一个声明our $foo;,突然不仅存在这个变量,而且还有一个神秘的价值.您必须搜索程序以查看该值可能来自何处.

cjm*_*cjm 5

我们声明了一个包变量的词法别名.这意味着它的范围就像my.不同之处在于它由包变量支持,因此当您退出范围时,变量不会消失.只有别名消失了.

因此,如果您使用$::fooour $foo再次创建另一个别名,您的程序将按预期工作.