我正在看这个question,当我在玩耍时,我遇到了这个:
#! /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
是的,我确实关闭了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.
嗯...我得到相同的“变量”$ foo“未导入./test.pl第12行。”如果我已完成my $foo = "bar";
错误。当我使用my
时,我会理解这一点,因为一旦我们离开块,就没有变量$foo
。但是,our
变量被认为是包范围。我可以理解$foo
当时可能没有值,但是这个?
此外,“变量”$ foo“未在./test.pl第12行导入。”是什么意思?我理解包和导入,但这里只有一个包,main
。 $foo
应位于main
包中。它不需要导入。
我的包变量发生了什么,它在超出范围后似乎不在包中?
因此,如果您使用了
$::foo
,或者再次使用our $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
现在,打印出来:
bar
bar
正如所有回答的人所指出的那样,our
只是为同名的包变量创建一个别名,并且词法作用域。这意味着一旦别名超出范围,我就可以使用$main::foo
访问$foo
的值。这是我以前从未意识到的事情。
但是,正如cjm指出的那样,重新声明our $foo;
会恢复别名,而现有的$main::foo
会将别名更改为新的$foo
。当我重新声明our $foo;
时,$foo
的值已恢复。
关于our
变量的事情之一可能会让人感到困惑。你看到一个声明our $foo;
,突然不仅存在这个变量,而且它有一个神秘的价值。您必须搜索程序以查看该值可能来自何处。
答案 0 :(得分:5)
Our声明包变量的词法别名。这意味着它的范围就像my
一样。不同之处在于它由包变量支持,因此当您退出范围时,变量不会消失。只有别名消失了。
因此,如果您使用$::foo
或再次使用our $foo
创建了另一个别名,您的程序将按预期工作。
答案 1 :(得分:2)
答案 2 :(得分:2)
perldiag说:“变量”$ foo“未在./test.pl第12行导入。”意思?
实际上使用“use strict”时,您引用了一个全局变量 你显然认为是从另一个模块导入的,因为 导出的其他同名(通常是子程序) 那个模块。这通常意味着你把错误的搞笑角色放在了 你变量的前面。
这没有任何意义,因为你没有导入任何东西。它不应该由您的代码发出。 Perl试图帮助诊断严格的错误,但是错了。忽略警告。
但是,我们的变量假设是包范围
那不是真的。 our
创建一个词法变量,就像my
一样。该变量别名为具有相同名称的包变量。
package Foo;
our $x; # Equivalent to: alias my $x = $Foo::x;
$Foo::x = 123;
package Bar;
$Bar::x = 456;
print("$x\n"); # 123
(alias
由Data :: Alias提供。)