为什么添加use strict; use warnings;
后我的代码无效?有没有办法让它发挥作用?
以前,工作代码是:
#!/usr/bin/perl -s
print "x: $x\n";
print "y: $y\n";
我运行的命令是perl -s test.pl -x="hello" -y="world"
。输出是:
x: hello
y: world
但是,在我添加use strict; use warnings;
后,我收到了以下错误:
Variable "$x" is not imported at test.pl line 4.
Variable "$y" is not imported at test.pl line 5.
Global symbol "$x" requires explicit package name at test.pl line 4.
Global symbol "$y" requires explicit package name at test.pl line 5.
Execution of test.pl aborted due to compilation errors.
我知道我需要声明my $x
和my $y
来解决第3和第4错误。但前两个错误意味着什么,我该如何克服它?
答案 0 :(得分:9)
实际上,将这些变量声明为词法(my
)变量无济于事,因为它太“迟”了:-s
开关已经设置了它们。它设置全局(包)变量(在您的情况下为$main::x
和$main::y
,或 - 作为特殊速记 - $::x
和$::y
)。如果您不想使用其包限定名称来引用它们,那么您可以使用our
声明来指示裸名称$x
和$y
是指当前包中的$x
和$y
:
our ($x, $y);
print "x: $x\n";
print "y: $y\n";
(对于指出你可以使用our
来解决问题的帽子提示。)
或者,您可以将全局变量复制到具有相同名称的词法变量中:
my ($x, $y) = ($::x, $::y);
print "x: $x\n";
print "y: $y\n";
这将处理两组诊断。
答案 1 :(得分:4)
您正在使用一个基本的开关解析器perl -s
,它使用全局变量。要使它与use strict
一起使用,你需要引用全局变量:$main::x
正如ruakh指出的那样。
但即便如此,词汇变量(用my
声明)在几乎所有情况下都是可取的。只是做:
use strict;
use warnings;
my ($x, $y) = @ARGV;
print "x: $x\n";
print "y: $y\n";
并使用:
perl test.pl hello world
有关更详细和类似开关的处理,请查看Getopt::Long模块。
答案 2 :(得分:2)
要了解任何Perl错误/警告的含义,您可以参考perldiag
。
具体来说,对于“未导入”,它说:
变量“%s”未导入%s
(W misc)实际上,使用“use strict”,你引用了一个你认为是从另一个模块导入的全局变量,因为该模块导出了同名的其他东西(通常是子程序)。这通常意味着你在变量的前面添加了错误的有趣角色。
基本上,Perl对你未声明的身份识别者$x
进行了2次不同的猜测 - 它是
禁止在strict
下使用的包范围全局(“全局符号”$ x“需要显式包”)
或尝试使用另一个应该已导入但尚未导入的包变量(“变量”$ x“未导入”)。
Perl无法分辨这两种理论的正确性,因此吐出两种可能性。后一个错误(全局符号“$ x”需要显式包名称)在这种情况下是正确的 - 它是原始预严格代码中的全局变量。