为什么调试器在`use`语句中停止?

时间:2016-10-02 22:44:23

标签: perl debugging

当我们将此代码括在大括号中时:

#!/usr/bin/env perl

{
    use warnings 'void';
    1;
}

调试器在use warnings 'void'语句停止:

main::(/home/kes/tmp/t3.pl:4):      use warnings 'void';
  DB<1> l 1-20
1   #!/usr/bin/env perl
2   
3   {
4==>    use warnings 'void';
5:      1;
6   }
7   

但如果我们不这样做:

#!/usr/bin/env perl


use warnings 'void';
1;

调试器不会停在use warnings 'void'语句:

main::(/home/kes/tmp/t3.pl:5):      1;
  DB<1> l 1-20
1   #!/usr/bin/env perl
2   
3   
4:      use warnings 'void';
5==>    1;
6   
7

但是,正如我们所看到的,line 4仍然标记为易碎。

这些例子有何不同之处
以及为什么调试器不会停在line 4上?

1 个答案:

答案 0 :(得分:4)

use语句永远不会添加到已编译的程序中,因为它在编译时执行。

$ perl -MO=Concise,-exec -e'use warnings qw( void ); f()'
1  <0> enter
2  <;> nextstate(main 2 -e:1) v:{
3  <0> pushmark s
4  <#> gv[*f] s/EARLYCV
5  <1> entersub[t2] vKS/TARG
6  <@> leave[1 ref] vKP/REFC
-e syntax OK

因此,调试器永远不会在use语句上停止。让我们看看两个程序的编译形式:

$ perl -MO=Concise
{
   use warnings qw( void );
   1;
}
^D
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -:2) v:{ ->3
5     <2> leaveloop vK/2 ->6
3        <{> enterloop(next->5 last->5 redo->4) v ->4
-        <@> lineseq vKP ->5
4           <;> nextstate(main 3 -:3) v:{ ->5
-           <0> ex-const v ->-
- syntax OK

$ perl -MO=Concise
use warnings qw( void );
1;
^D
3  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -:2) v:{ ->3
-     <0> ex-const v ->3
- syntax OK

nextstate操作设置运行时警告的行号。 (例如,-:2表示从STDIN读取的代码的第2行。)调试器也使用它们来知道在哪里中断并在当前语句的源文件中找到该行。

第二个代码段只有一个运行时语句,因此它只有一个nextstate操作符,调试器停止运行。

然而,第一个片段有两个陈述。裸循环({ ... })和常量。裸循环创建一个nextstate op,其中第一个非空白字符的行跟在{之后,恰好是use warnings;。我不确定为什么会这样做。