在Eclipse中使用Perl EPIC调试器时,为什么执行不会停在'do'模块的断点处,而是停在'require'模块?
script.pl
use strict;
#use sample; # <-- Execution stops at breakpoint in printMessage() of 'sample.pm'
#require sample; # <-- Execution stops at breakpoint in printMessage() of 'sample.pm'
#do 'sample.pm'; # <-- Execution DO NOT STOP at breakpoint in printMessage() of 'sample.pm'
sample::printMessage();
sample.pm
package sample;
sub printMessage
{
print 'new message!';
}
1;
答案 0 :(得分:4)
我在Komodo IDE和命令行中尝试了这个并获得了相同的结果。
如果您use
或require
文件,Perl会将文件名保存在%INC
中。这确保了文件只加载一次。您可以在许多不同的其他模块中require
使用相同的模块,并使用sample::printMessage()
之类的功能。第一个require
将完成,其他所有内容都将被忽略,因为$INC{'sample'} = './sample.pm'
中已存在密钥%INC
。
require sample;
require sample;
require sample;
sample::printMessage();
__END__
new message!
如果您use
模块而不是require
,则同样适用,因为use
只有require
而import
位于BEGIN
阻止。在这两种情况下,Perl都记得这一点。我的假设(没有找到证明证明的文档)是,调试器能够做同样的事情,甚至读取内部%INC
。
现在,如果您do
某个文件,%INC
机制不已触发,则意味着您可以反复do
该文件。它不关心文件的名称。这样做的结果是,如果您do
该文件多次,即使没有use warnings
,它也会抱怨。
do 'sample.pm';
do 'sample.pm';
do 'sample.pm';
__END__
Subroutine printMessage redefined at sample.pm line 4.
Subroutine printMessage redefined at sample.pm line 4.
new message!
我的猜测是调试器也不记得了,因此它不知道它已加载sample.pm
。 doc说:
使用EXPR的值作为文件名并执行。的内容 将文件作为Perl脚本。
do 'stat.pl';
很像
eval `cat stat.pl`;
因此它只会在文件中徘徊并执行内容。没有%INC
。调试器没有文件名(顺便提一下,它是EPIC中的调试器,与Komodo IDE中的调试器一样,在命令行上,图形调试器只是连接到Perl调试器)。因此,当代码显示do
时,您的断点将被忽略。
如果您希望调试器在sample.pm
中的第5行停止,即使您do
,也可以通过将$DB::single = 1;
添加到上面的行来告诉调试器。< / p>
package sample;
sub printMessage
{
$DB::single = 1;
print 'new message!';
}
perldebug中记录了这一点。它将使调试器停在下一行,相当于在调试器中键入 s ,或单击EPIC调试器中的单步按钮。
另见:
%INC