如果在Perl脚本中看到这样的警告信息,你可能有大麻烦了。

变量赋值

给某个变量赋值但是从来没有用它,或者变量之只用一次但没有给它赋值,这一般表示在代码中隐含某个错误。

大概唯一“合理”的解释就是输入错。

这有个例子就是只对变量赋值

use warnings;

$x = 42;

会产生如下警告:

Name "main::x" used only once: possible typo at ...

你可能会对"main::"部分没有$符号感到奇怪。这是因为Perl的变量默认是在"main"命名空间下。 或许有好多东西都称为"main::x",但是只有一个在将$作为前导符号。如果这听起来很迷惑人,不要担心。 因为它本来就很复杂,幸运的是你不需要总是处理这样的问题。

只取值

如果你只使用某个变量一次

use warnings;

print $x;

那么会得到两条错误信息:

Name "main::x" used only once: possible typo at ...
Use of uninitialized value $x in print at ...

其中之一是我们正在讨论的,而另一个将会在使用未初始化的值中讨论。

有什么输入错误?

你可能会这么问。

设想一下,有人使用了一个变量$l1,之后你要使用同一个变量,但是你却输入了$ll。可能是因为在你的字体中它们看起来很像。

或者变量是$color,但你是英国人,你可能自然而然地在考虑同一个东西的时候输入$colour

再或者有个变量是$number_of_misstakes,而你没有注意到原来的变量就有输入错误,然后你输入了$number_of_mistakes

理解了吧。

如果幸运的话,你可能只犯一次错误,不过如果你倒霉地使用了两次错误的变量,这样的警告就不会出现了。毕竟你两次使用了同一个变量两次,可能有个好的理由。

那么如果避免呢?

尽可能不要使用有歧义的字母,并且在输入变量名字的时候尽量小心一点。

如果想真正的解决这个问题,你可以使用use strict

use strict

上面的例子中你发现我没有使用strict。如果用的话,就不会有可能输入错误的警告,取而代之的是编译时错误:Global symbol requires explicit package name

即便你多次使用错误的变量也会出现这样的提示。

当然,看到错误后有些人会匆忙地在错误的变量前面加上"my",但你不会这么做,对么?正确的做法是好好思考问题,直到搜索到真正的变量。

如果没有使用strict通常会看到这个警告。

然后你就陷入了麻烦之中。

Other cases while using strict

GlitchMr和一位匿名用户在评论还另外举了几个例子:

下面的代码也会产生警告。

use strict;
use warnings;

$main::x = 23;

警告信息是:Name "main::x" used only once: possible typo ...

'main'和下面例子中的Mister是哪来的应该很清楚。(提示:它是包名,这里没有关于包名的错误)在下个例子中包名是'Mister'。

use strict;
use warnings;

$Mister::x = 23;

警告是 Name "Mister::x" used only once: possible typo ....

下面的例子会产生两条警告信息:

use strict;
use warnings;

use List::Util qw/reduce/;
print reduce { $a * $b } 1..6;

Name "main::a" used only once: possible typo at ...
Name "main::b" used only once: possible typo at ...

Perl Monks might know. 这是因为$a$b在内建的排序函数中是特殊变量,所以你可以不用声明, 但此处你只使用了一次。(事实上,对于这里为什么会产生警告信息我也不是很清楚,同样的代码 在sort函数中就不会有问题,请参阅Perl Monks。)