Почему отладчик Perl не останавливается на точках останова с помощью do, а останавливается с помощью require?

При использовании отладчика Perl EPIC в Eclipse, почему выполнение не останавливается на точках останова в модуле '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;

1 ответ

Решение

Я попробовал это в 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, Док говорит:

Использует значение EXPR в качестве имени файла и выполняет содержимое файла как скрипт Perl.

do 'stat.pl';

во многом как

eval `cat stat.pl`;

Таким образом, он только хлебает в файле и выполняет содержимое. нет %INC, Нет имени файла для отладчика (который, кстати, является тем же отладчиком в EPIC, что и в Komodo IDE, как и в командной строке, графические просто подключаются к отладчику Perl). Из-за этого ваша точка останова игнорируется, когда код говорит do,

Если вы хотите, чтобы ваш отладчик остановился на строке 5 в sample.pm даже если ты do это, вы можете сказать отладчику сделать это, добавив $DB::single = 1; на линию выше.

package sample;

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

Это задокументировано в perldebug. Это заставит отладчик остановиться на следующей строке и будет эквивалентно вводу s в отладчике или нажатию кнопки " один шаг" в вашем EPIC-отладчике.


Смотрите также:

Другие вопросы по тегам