如何使用perl命令行参数避免错误并使用strict

时间:2012-03-07 03:34:56

标签: perl command-line

为什么添加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 $xmy $y来解决第3和第4错误。但前两个错误意味着什么,我该如何克服它?

3 个答案:

答案 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次不同的猜测 - 它是

  1. 禁止在strict下使用的包范围全局(“全局符号”$ x“需要显式包”)

  2. 或尝试使用另一个应该已导入但尚未导入的包变量(“变量”$ x“未导入”)。

  3. Perl无法分辨这两种理论的正确性,因此吐出两种可能性。后一个错误(全局符号“$ x”需要显式包名称)在这种情况下是正确的 - 它是原始预严格代码中的全局变量。