为什么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 和命令行中尝试了这一点,并得到了相同的结果。

如果您userequire文件,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 调试器中的单步按钮。


也可以看看: