Dan*_*umb 5 perl warnings initialization
我对一些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};
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的代码时,我收到以下警告:
Use of uninitialized value in numeric gt (>) at Performance/BadSpan.pm line 67 (#1)
Run Code Online (Sandbox Code Playgroud)
第67行等同于该if($result != 0) {
行.
我的问题是双重的:
$result
未定义,当有在它之前的一些后卫代码,确保它被定义!=
'被'优化'到a >
和a <
?什么是perl
?
特定
use strict; use warnings;
my $x;
if ( $x ) {
print "here\n";
}
elsif ( $x > 1 ) {
print "there\n";
}
Run Code Online (Sandbox Code Playgroud)
perl
5.10.1正确输出:
Use of uninitialized value $x in numeric gt (>) at C:\Temp\t.pl line 8.
鉴于这elsif
不是独立的,而是if
声明的一部分,早期版本中可能存在一个错误,它报告了封闭if
语句的行号.
这篇文章与此条目perltodo
似乎相关:
消除警告中不正确的行号
这段代码
Run Code Online (Sandbox Code Playgroud)1. use warnings; 2. my $undef; 3. 4. if ($undef == 3) { 5. } elsif ($undef == 0) { 6. }
用于产生此输出:
Run Code Online (Sandbox Code Playgroud)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和之间没有下一个OP
elsif
,因此PL_curcop
仍然报告当前正在执行的行是第4行.解决方案是为每个注入一个下一个OPelsif
,尽管事实证明,下一个OP需要是一个空的OP,而不是一个实时的下一个OP,否则其他行号被误报了.(积木!)问题比一般情况更为普遍
elsif
(尽管elsif
案例是最常见且最令人困惑的).理想情况下这个代码Run Code Online (Sandbox Code Playgroud)1. use warnings; 2. my $undef; 3. 4. my $a = $undef + 1; 5. my $b 6. = $undef 7. + 1;
会产生这个输出
Run Code Online (Sandbox Code Playgroud)Use of uninitialized value $undef in addition (+) at wrong.pl line 4. Use of uninitialized value $undef in addition (+) at wrong.pl line 7.
(而不是第4和第5行),但这似乎要求每个OP都携带(至少)行号信息.
可能有用的是在BASEOP结构之前的内存中有一个可选的行号,在op中有一个标志位来说明它是否存在.最初在编译期间,每个OP都会携带其行号.然后向优化器添加一个延迟传递(可能与重新装入optree相结合),它会查看执行路径图的每个边缘上的两个操作.如果行号更改,则使用此信息标记目标OP.跟踪所有路径后,将每个op替换为带有nextstate-light op(仅更新
PL_curcop
)的标志,然后将控制权传递给真正的op.然后,所有操作都将被不存储行号的变体替换.(从逻辑上讲,为什么它与重新包装optree一起效果最好,因为它已经在复制/重新分配所有OP)(虽然我应该注意到,我们不确定为一般情况做这件事是值得的)
这是实际的提交.鉴于提交发生在2008年4月,我假设修复程序包含在5.8.9版本中(参见perlhist).