为什么 Perl 在这个警告消息中提供了一个误导性的行号? [英] Why does Perl provide a misleading line number in this warning message?

查看:53
本文介绍了为什么 Perl 在这个警告消息中提供了一个误导性的行号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经隔离了一个案例,其中 Perl 在警告消息中提供了一个非常具有误导性的行号.我在 Strawberry Perl 5.16.3 中测试了以下内容.

I have isolated a case where Perl provides a very misleading line number in a warning message. I tested the below in Strawberry Perl 5.16.3.

use strict;
use warnings;

my $choice = 0;

while ($choice == 0){

    #This is not numeric
    $choice = '5,6,7';

    if ($choice eq '-4'){
        print "This isn't going to happen\n";
    }
}

当您运行此程序时,您将收到警告消息 Argument "5,6,7" is not numeric in numeric eq (==) at example.pl line 11.但是第 11 行对应于 if ($choice eq '-4'){ 行,它不可能导致此警告消息,因为它不包含数字比较.

When you run this, you will get the warning message Argument "5,6,7" isn't numeric in numeric eq (==) at example.pl line 11. But line 11 corresponds to the line if ($choice eq '-4'){ which cannot possibly cause this warning message because it does not contain a numeric comparison.

看起来实际上发生的是 Perl 前进到下一个比较,while ($choice == 0){,但是用于警告消息的行计数器不前进.

It seems what's actually happening is that Perl advances to the next comparison, while ($choice == 0){, but the line counter used for the warning message does not advance.

让这个特殊情况变得更糟的是,由于坏"比较是循环条件,它实际上远离提供的行.在我的(简化前)脚本中,它与提供的行号相距数百行.

What makes this particular case worse is that, since the "bad" comparison is the loop condition, it is actually far away from the provided line. In my (pre-simplification) script, it was hundreds of lines away from the provided line number.

这是一个错误还是只是解析器的一个不幸的限制?

Is this a bug or just an unfortunate limitation of the parser?

推荐答案

存储每个操作符实例的位置会很昂贵.作为妥协,Perl 只跟踪语句的位置.它通过在每个语句的开头添加一个位置设置操作码来实现.if 语句是执行 $choice == 0 之前要启动的最后一条语句,因此报告警告为来自该行.

It would be expensive to store the location of each operator instance. As a compromise, Perl only tracks the location of statements. It does so by adding a location-setting opcode at the start of every statement. The if statement is the last statement to be started before $choice == 0 is performed, so the warning is reported as coming from that line.

$ perl -MO=Concise,-exec a.pl
1  <0> enter
2  <;> nextstate(main 3 a.pl:4) v:*,&,{,x*,x&,x$,$
3  <$> const[IV 0] s
4  <0> padsv[$choice:3,12] sRM*/LVINTRO
5  <2> sassign vKS/2
6  <;> nextstate(main 4 a.pl:6) v:*,&,{,x*,x&,x$,$           <--- Location set to line 6
7  <{> enterloop(next->k last->p redo->8) v                  <--- Start of while loop
l  <0> padsv[$choice:3,12] s                                 <--- $choice == 0
m  <$> const[IV 0] s
n  <2> eq sK/2
o  <|> and(other->8) vK/1
8      <;> nextstate(main 6 a.pl:9) v:*,&,x*,x&,x$,$
9      <$> const[PV "5,6,7"] s
a      <0> padsv[$choice:3,12] sRM*
b      <2> sassign vKS/2
c      <;> nextstate(main 6 a.pl:11) v:*,&,x*,x&,x$,$        <--- Location set to line 11
d      <0> padsv[$choice:3,12] s                             <--- Start of if statement
e      <$> const[PV "-4"] s
f      <2> seq sK/2
g      <|> and(other->h) vK/1
h          <0> pushmark s
i          <$> const[PV "This isn't going to happen\n"] s
j          <@> print vK
k      <0> unstack v
           goto l                                            <--- Jump back to loop expr
p  <2> leaveloop vKP/2
q  <@> leave[1 ref] vKP/REFC
a.pl syntax OK

这是一个已知的限制.我不知道他们为什么不简单地在循环表达式中放置一个 nextstate 操作.

This is a known limitation. I don't know why they don't simply put a nextstate op in the loop expression.

这篇关于为什么 Perl 在这个警告消息中提供了一个误导性的行号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆