【问题标题】:Use of uninitialized value warning while checking "if defined <variable>"检查“if defined <variable>”时使用未初始化值警告
【发布时间】:2016-04-01 01:00:12
【问题描述】:

这是一个大代码的sn-p,如果没有匹配则打印Use of uninitialized value $match in string eq at &lt;script path&gt; line 7.

我正在使用if (!defined $match),它不应该抑制这个警告吗?我正在使用 Perl 5.18 版

my $match = '';
my $prematch = '';
my $i = 1;
$obj->{comm}->print( $command ); #$obj->{comm} is Net::Telnet
while ($match eq '' and $i < 3) {
   ( $prematch, $match ) = $obj->{comm}->waitfor( Match => "/$pattern/");
   print "\npattern not found, try again..." if (!defined $match); #line 7
   $i++;
}

【问题讨论】:

  • 警告是关于eq,而不是defined,所以问题可能出在while ($match eq '' and $i &lt; 3) {。我猜 $obj-&gt;{comm}-&gt;waitfor 正在将 $match 设置为 undef。

标签: perl


【解决方案1】:

waitfor 似乎将 $match 设置为 undef,至少在某些时候。

while (! length $match &amp;&amp; $i &lt; 3) 是检查它是否为空或未定义的最简单方法,至少在非古代 perls 中是这样。或者,如果 waitfor 从未将其设置为空字符串,请不要将其设置为您自己 (my $match;) 并使用 while (! defined $match &amp;&amp; $i &lt; 3)

【讨论】:

  • 我不热衷于将重试次数的测试与比赛的成功相结合。 while (! length $match &amp;&amp; $i &lt; 3) 不会对我大喊尝试两次然后放弃
  • @Borodin 是的,你的答案更好。
【解决方案2】:

这很尴尬,因为您必须初始化 $i(它不是索引,因此应该是 $n)和 $match 只是为了设计一个 do ... while 而不是 @987654326 @do`

这看起来像是一个无限循环的情况,其中插入了对结束循环条件的检查,但您只想尝试两次,所以一个简单的for 循环就可以了

大概是这样的吧?

$obj->{comm}->print($command);

my $match;

for ( 1 .. 2 ) {

    my $prematch;

    ($prematch, $match) = $obj->{comm}->waitfor(Match => "/$pattern/");

    last if defined $match;

    print "\npattern not found, try again...";
}

# Here $match will still be undefined if there was no match after two tries

【讨论】:

  • 我会做(my $prematch, $match) = ...,但我知道这会困扰一些人。我也会做for my $try (1..2) 并避免设置一个未使用的$_
  • @ysth: my ($prematch, $match) 不起作用,因为$match 需要更大的范围。不过,关于循环控制变量的要点很好——我还不知道 Perl 6 对 $_ 做了什么,但我对我所看到的其他一切都很满意
  • 我的我在括号里
  • @ysth:这有什么改变吗?
  • 它只影响以下变量,不影响列表中的任何其他内容
【解决方案3】:

应该这样做

my $match = '';
my $prematch = '';
my $i = 1;
$obj->{comm}->print( $command ); #$obj->{comm} is Net::Telnet
while (!$match and $i < 3) {
   ( $prematch, $match ) = $obj->{comm}->waitfor( Match => "/$pattern/");
   print "\npattern not found, try again..." if (!$match); #line 7
   $i++;
}

通过将 '' 分配给 $match 您实际上是在定义它。如果 $match = undef; 您的代码将起作用像这样

my $match = undef;
my $prematch = '';
my $i = 1;

while (!defined $match and $i < 3) {
    print "\npattern not found, try again..." if (!defined $match); #line 7
    $i++;
}

【讨论】:

    猜你喜欢
    • 2012-06-05
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 2020-10-25
    相关资源
    最近更新 更多