为什么魔术Perl内部变量的解决方法有效?

时间:2016-06-06 19:49:38

标签: perl debugging

t2.pl

1;
2;
3;

t.pl

package DB;

sub DB {
    print "HERE";

    our(undef, $f, undef) =  caller;

    # This does not work
    # my $ref =  \%{ "main::_<$f" };
    # $ref->{ 3 } =  {};

    # This does not work
    # *x =  $main::{ "_<$f" };
    # $x{ 3 } =  {};

    *dbline =  $main::{ "_<$f" };
    $dbline{ 3 } =  {};

    $DB::single =  0;
}

1;
PERL5DB="BEGIN{ require 't.pl' }" perl -d t2.pl

运行此代码时,您获得HEREHERE,但如果不使用*dbline对其进行别名,则神奇的Perl变量无效。

因此,当您将前两个示例更改为:

*dbline =  $main::{ "_<$f" }; # <<<<<<<<< With this it works!!!!
*x =  $main::{ "_<$f" };
$x{ 3 } =  { };

断点开始起作用。 (这适用于Perl 5.14.4)

为什么它会以这种方式运作?

DOC

1 个答案:

答案 0 :(得分:6)

之前已经reported

  

perldebguts说:

     
      
  • 每个哈希%{"_<$filename"}包含由行号键入的断点和操作。单个条目(与整个哈希相对)是可设置的。
  •   
     

这意味着%{"_<..."}上设置的断点适用于指定文件。事实并非如此,因为每个%{"_<..."}哈希都会在@DB::dbline中的行上设置断点,而不管它引用哪个文件。假设调试器在设置任何断点之前将*DB::dbline别名为*{"_<..."}

     

因此,所有%{"_<..."}哈希都是相同的。

     

是否应该扩展文档以匹配实现?或者我们是否应该更改实现以使每个%{"_<..."}哈希在其对应的@{"_<..."}数组上工作?后者似乎对我更有用。

在5.20.0中,行为为changed,因此您不必使用别名@DB::dbline

$ PERL5DB='
  sub DB::DB {
      ($p,$f,$l) = caller;
      print "$f:$l\n";
      ${"::_<$f"}{3} = 1; # no need for alias
      $DB::single = 0
  }
' perl -d foo
foo:1
foo:3