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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1680904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 18:22:26  来源:igfitidea点击:

Why does Perl complain about "Use of uninitialized value" in my CGI script?

perlapachevariableswarnings

提问by Mike

I am cleaning my Perl code for production release and came across a weird warning in the Apache error log.

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

It says:

它说:

[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.

[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.

The relevant code is here:

相关代码在这里:

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;
}

So, why the warning of an uninitialized variable as it is clearly initialized?

那么,为什么会警告未初始化的变量,因为它已明确初始化?

回答by Clinton Pierce

The warning simply means that $namewas never filled with a value, and you tried doing a substitution operation (s///) on it. The default value of a variable is undefined (undef).

该警告仅表示$name从未填充值,并且您尝试对其执行替换操作 ( s///)。变量的默认值是 undefined ( undef)。

Looking back through your script, $namegets its value from @_. This means either @_was empty, or had its first value as undef.

回顾你的脚本,$name@_. 这意味着要么@_为空,要么第一个值为undef

回答by brian d foy

Depending on what your subroutine needs to do, validate your values before you use them. In this case, since you need something in $name, croakif there isn't something in that variable. You'll get an error message from the perspective of the caller and you'll find the culprit.

根据您的子例程需要做什么,在使用之前验证您的值。在这种情况下,由于您需要 中的某些内容$namecroak如果该变量中没有内容。您将从调用者的角度收到一条错误消息,您将找到罪魁祸首。

Also, you can lose the complexity of the conditional operator chain by making it a hash lookup, which also gives you a chance to initialize $name_option. In your fallback case, you leave $name_optionundefined:

此外,您可以通过将其设为哈希查找来降低条件运算符链的复杂性,这也使您有机会初始化$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;
        }

    ...
    }
}

回答by Yaakov Belch

Debug by divide and conquer

分而治之调试

It is quite usual to run into bugs that are "obviously impossible" --- at the first glance. I usually try to confirm my assumptions with simple print statements (or equivalent ways to get some information back from the program: For CGI scripts, a simple print can ruin your headers).

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

So, I would put a statement like

所以,我会发表这样的声明

print "testing: ", defined($name)? "defined: '$name'" : "undef", "\n";

into the code at the suspected line. You might be surprised about the possible output options:

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

  • "testing: undef" --- this means that your function was called with an undefined first argument. Unlikely but possible. You may want to use caller() to find out from where it was called and check the data there.
  • no output at all! Maybe you look at the wrong source file or at the wrong line. (I don't suspect that's the case here, but it does happen to me).
  • "testing: defined: 'some data'" --- oops. ask a question on stackoverflow.
  • "testing: undef" --- 这意味着你的函数是用未定义的第一个参数调用的。不太可能,但可能。您可能希望使用 caller() 找出它被调用的位置并检查那里的数据。
  • 根本没有输出!也许您查看了错误的源文件或错误的行。(我不怀疑这里是这种情况,但它确实发生在我身上)。
  • “测试:定义:'一些数据'”---哎呀。问一个关于 stackoverflow 的问题。