我对某些Perl代码发出了一个奇怪的警告,我希望SO大脑可以提供帮助。
有问题的代码是:
sub add_observation {
my $self = shift;
my $observation = shift;
my $result = $observation->get_datum_result($self->{datum_name});
if(!(defined $result)) {
croak("Datum '$self->{datum_name}' not defined for this observation: ". Dumper($observation));
}
$self->{result} |= $result;
my $observation_time = $observation->get_time();
if($self->{result} == 0){
$self->set_start_time($observation_time);
}
if($result != 0) {
$self->set_end_time($observation_time);
$self->{end_threshold} = $observation_time->epoch() + $self->{timeout};
}
elsif($observation_time->epoch() > $self->{end_threshold}) {
$self->{complete} = 1;
}
return $self->{result};
}
当我运行我的代码时,我收到以下警告:
Use of uninitialized value in numeric gt (>) at Performance/BadSpan.pm line 67 (#1)
第67行等同于if($result != 0) {
行。
我的问题有两个:
$result
未定义,前面有一些保护代码确保 定义!=
被“优化”为>
和{{1 }}?答案 0 :(得分:8)
perl
的版本是什么?
给出
use strict; use warnings;
my $x;
if ( $x ) {
print "here\n";
}
elsif ( $x > 1 ) {
print "there\n";
}
perl
5.10.1正确输出:
Use of uninitialized value $x in numeric gt (>) at C:\Temp\t.pl line 8.
鉴于elsif
不是独立的,而是if
语句的一部分,早期版本中可能存在一个错误,它报告了封闭if
语句的行号
This post和this entry in perltodo
似乎相关:
消除警告中的错误行号
此代码
1. use warnings; 2. my $undef; 3. 4. if ($undef == 3) { 5. } elsif ($undef == 0) { 6. }
用于产生此输出:
Use of uninitialized value in numeric eq (==) at wrong.pl line 4. Use of uninitialized value in numeric eq (==) at wrong.pl line 4.
第二个警告的行被误报了 - 它应该是第5行.Rafael解决了这个问题 - 问题出现了,因为在if和
elsif
的执行之间没有下一个OP,因此{{1仍然报告当前正在执行的行是第4行。解决方案是为每个PL_curcop
注入一个下一个OP,尽管事实证明,下一个OP需要是一个空的OP,而不是一个活的下一个OP ,否则其他行号被误报了。 (积木!)问题比
elsif
更普遍(尽管elsif
案例是最常见且最令人困惑的)。理想情况下这段代码elsif
会产生此输出
1. use warnings; 2. my $undef; 3. 4. my $a = $undef + 1; 5. my $b 6. = $undef 7. + 1;
(而不是第4和第5行),但这似乎要求每个OP都携带(至少)行号信息。
可能有用的是在BASEOP结构之前的内存中有一个可选的行号,在op中有一个标志位来说明它是否存在。最初在编译期间,每个OP都会携带其行号。然后向优化器添加一个延迟传递(可能与重新装入optree相结合),它会查看执行路径图的每个边缘上的两个操作。如果行号更改,则使用此信息标记目标OP。跟踪所有路径后,将每个op替换为带有nextstate-light op(仅更新
Use of uninitialized value $undef in addition (+) at wrong.pl line 4. Use of uninitialized value $undef in addition (+) at wrong.pl line 7.
)的标志,然后将控制权传递给真正的op。然后,所有操作都将被不存储行号的变体替换。 (从逻辑上讲,为什么它与重新包装optree一起效果最好,因为它已经复制/重新分配所有OP)(虽然我应该注意到,我们不确定为一般情况做这件事是值得的)
答案 1 :(得分:2)
行
上的是数字gt(>
)
elsif($observation_time->epoch() > $self->{end_threshold}) {
这是与第67行的elsif
相关联的if
。也许警告消息的行号错误。 $observation_time->epoch()
或$self->{end_threshold}
可能未定义吗?
答案 2 :(得分:0)
可能是>
子句中的elsif
。检查这些值。