为什么Perl会在我的CGI脚本中抱怨“使用未初始化的值”?

时间:2009-11-05 14:27:42

标签: perl apache variables warnings

我正在清理生产版本的Perl代码,并在Apache错误日志中遇到了一个奇怪的警告。

它说:

[Thu Nov 5 15:19:02 2009] Clouds.pm: Use of uninitialized value $name in substitution (s///) at /home/mike/workspace/olefa/mod-bin/OSA/Clouds.pm line 404.

相关代码在这里:

my $name         = shift @_;
my $name_options = shift @_;

$name_options = $name_options eq 'unique'     ? 'u'
              : $name_options eq 'overwrite'  ? 'o'
              : $name_options eq 'enumerate'  ? 'e'
              : $name_options =~ m/^(?:u|o|e)$/ ? $name_options
              : q();

if ($name_options ne 'e') {
   $name =~ s/ /_/g;
}

那么,为什么未初始化的未初始化变量的警告呢?

3 个答案:

答案 0 :(得分:12)

警告只是意味着$name从未填充过值,并且您尝试对其执行替换操作(s///)。变量的默认值未定义(undef)。

回顾一下您的脚本,$name@_获取其值。这意味着@_为空,或者其第一个值为undef

答案 1 :(得分:3)

根据您的子程序需要执行的操作,请在使用之前验证您的值。在这种情况下,如果在$namecroak中需要某些内容,如果该变量中没有内容。你会从调用者的角度得到一条错误信息,你会找​​到罪魁祸首。

此外,您可以通过使其成为哈希查找来丢失条件运算符链的复杂性,这也使您有机会初始化$name_option。在您的后备情况下,您将$name_option未定义:

use 5.010;

use Carp;

BEGIN {
my %valid_name_options = map {
    $_
    substr( $_, 0, 1 ),
    } qw( unique overwrite enumerate );

some_sub {
    my( $name, $name_options ) = @_;

    croak( "Name is not defined!" ) unless defined $name;
    $name_options = $valid_name_options{$name_options} // '';

    if ($name_options ne 'e') {
        $name =~ s/ /_/g;
        }

    ...
    }
}

答案 2 :(得分:1)

通过分而治疗进行调试

通常会遇到“显然不可能”的错误 - 乍一看。我通常尝试使用简单的打印语句来确认我的假设(或从程序中获取一些信息的等效方法:对于CGI脚本,简单的打印可能会破坏您的标题)。

所以,我会发表一个像

这样的声明
print "testing: ", defined($name)? "defined: '$name'" : "undef", "\n";

进入疑似行的代码。您可能会对可能的输出选项感到惊讶:

  • “testing:undef”---这意味着您的函数是使用未定义的第一个参数调用的。不太可能,但可能。您可能希望使用caller()来查找它的调用位置并检查那里的数据。
  • 根本没有输出!也许你看错了源文件或错误的行。 (我不怀疑这是这种情况,但确实发生在我身上)。
  • “测试:定义:'一些数据'”--- oops。在stackoverflow上提问。