5

在 Eclipse 中使用 Perl EPIC 调试器时,为什么执行不是在“do”模块中的断点处停止,而是在“require”模块处停止?

脚本.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();

样品.pm

package sample;

sub printMessage
{
    print 'new message!';   
}

1;
4

1 回答 1

4

我在 Komodo IDE 和命令行中尝试了这个并得到了相同的结果。

如果你userequire一个文件,Perl 将文件名保存在%INC. 这样可以确保文件只加载一次。您可以require在许多不同的其他模块中使用相同的模块并使用sample::printMessage(). 第一个require将完成,其他所有将被忽略,因为$INC{'sample'} = './sample.pm'.%INC

require sample;
require sample;
require sample;

sample::printMessage();

__END__
new message!

如果您use使用模块而不是requireing 它,这同样适用,因为use只有 arequire和 animport在一个BEGIN块中。在这两种情况下,Perl 都记住了这一点。我的假设(没有找到证明这一点的文档)是,调试器能够做同样的事情,甚至可以读取内部的%INC.

现在,如果您do是文件,则不会触发该%INC机制,这意味着您可以一遍又一遍地文件。它不关心文件的名称。其后果是,如果您多次提交文件,即使没有.dodouse 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. 医生

使用 EXPR 的值作为文件名并将文件的内容作为 Perl 脚本执行。

do 'stat.pl';

很大程度上就像

eval `cat stat.pl`;

所以它只在文件中啜饮并执行内容。没有%INC。调试器没有文件名(顺便说一下,EPIC 中的调试器与 Komodo IDE 中的调试器和命令行上的调试器相同,图形化的只是连接到 Perl 调试器)。因此,当代码显示时,您的断点将被忽略do

如果您希望调试器sample.pm即使在第 5 行停止,也可以通过添加到上面的行do来告诉调试器这样做。$DB::single = 1;

package sample;

sub printMessage
{
    $DB::single = 1;
    print 'new message!';
}

这记录在perldebug中。它将使调试器在下一行停止,相当于s在调试器中键入,或单击 EPIC 调试器中的单步按钮。


也可以看看:

于 2013-11-07T08:29:38.103 回答