为什么Perl调试器不会在断点处停止,而是停止使用require?

Inn*_*elt 5 eclipse debugging perl epic

在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();
Run Code Online (Sandbox Code Playgroud)

sample.pm

package sample;

sub printMessage
{
    print 'new message!';   
}

1;
Run Code Online (Sandbox Code Playgroud)

sim*_*que 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!
Run Code Online (Sandbox Code Playgroud)

use如果您使用module 而不是ing 它,则同样适用require,因为块中use只有 arequire和 an 。在这两种情况下,Perl 都记得这一点。我的假设(尚未找到证明这一点的文档)是,调试器能够执行相同的操作,甚至读取内部.importBEGIN%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!
Run Code Online (Sandbox Code Playgroud)

我的猜测是调试器也不记得,因此它不知道它已经加载了sample.pm。医生说:

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

do 'stat.pl';
Run Code Online (Sandbox Code Playgroud)

很大程度上就像

eval `cat stat.pl`;
Run Code Online (Sandbox Code Playgroud)

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

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

package sample;

sub printMessage
{
    $DB::single = 1;
    print 'new message!';
}
Run Code Online (Sandbox Code Playgroud)

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


也可以看看: