Могу ли я получить ручку к источнику?
Похоже, что в main есть символ под названием '_<-'
(без кавычек) таким же образом, как и другие вещи, которые выглядят как они могут быть дескрипторами: '_</usr/perl/lib/Carp.pm'
, например.
Или мне придется использовать фильтр источника, если я надеюсь прочитать источник ввода?
В ответ на mob: я не знаю, где будет включаться Debug. После того, как я дамп из базовой таблицы, дамп %INC показывает:
$VAR1 = {
'warnings/register.pm' => 'C:/strawberry/perl/lib/warnings/register.pm',
'XSLoader.pm' => 'C:/strawberry/perl/lib/XSLoader.pm',
'English.pm' => 'C:/strawberry/perl/lib/English.pm',
'Tie/Hash/NamedCapture.pm' => 'C:/strawberry/perl/lib/Tie/Hash/NamedCapture.pm',
'unicore/lib/Perl/_PerlIDS.pl' => 'C:/strawberry/perl/lib/unicore/lib/Perl/_PerlIDS.pl',
'unicore/Heavy.pl' => 'C:/strawberry/perl/lib/unicore/Heavy.pl',
'warnings.pm' => 'C:/strawberry/perl/lib/warnings.pm',
'utf8.pm' => 'C:/strawberry/perl/lib/utf8.pm',
'Config.pm' => 'C:/strawberry/perl/lib/Config.pm',
'overloading.pm' => 'C:/strawberry/perl/lib/overloading.pm',
'Symbol.pm' => 'C:/strawberry/perl/lib/Symbol.pm',
'Carp.pm' => 'C:/strawberry/perl/lib/Carp.pm',
'bytes.pm' => 'C:/strawberry/perl/lib/bytes.pm',
'Exporter/Heavy.pm' => 'C:/strawberry/perl/lib/Exporter/Heavy.pm',
'utf8_heavy.pl' => 'C:/strawberry/perl/lib/utf8_heavy.pl',
'strict.pm' => 'C:/strawberry/perl/lib/strict.pm',
'Exporter.pm' => 'C:/strawberry/perl/lib/Exporter.pm',
'vars.pm' => 'C:/strawberry/perl/lib/vars.pm',
'constant.pm' => 'C:/strawberry/perl/lib/constant.pm',
'Errno.pm' => 'C:/strawberry/perl/lib/Errno.pm',
'overload.pm' => 'C:/strawberry/perl/lib/overload.pm',
'Data/Dumper.pm' => 'C:/strawberry/perl/lib/Data/Dumper.pm'
};
2 ответа:
Или мне придется использовать фильтр источника, если я надеюсь прочитать источник ввода?
Если исходный файл имеет тег
__END__
или__DATA__
, то доступен файловый хэндлDATA
. ...это само по себе скучно. Интересно то, что вы можетеseek
занять позицию 0, и это приведет вас к началу исходного файла:use Carp; print "Just another Perl hacker,\n"; eval { no warnings qw/unopened/; seek DATA, 0, 0 or croak "Script lacking __END__ or __DATA__ tag has no DATA filehandle."; }; if( !$@ ) { while(<DATA>){ print; } } else { carp $@; } __END__
Этот скрипт будет выполнен (печать 'просто еще один хакер Perl,'), а затем завершится печатью собственного источник.
В приведенном выше коде, если блок
eval
ловит исключение, резервным вариантом может быть использование FindBin и$0
, открытие исходного файла, а затем его чтение. Собирая все это вместе, вот как это выглядит:BEGIN { use Carp; sub read_source { my $source; local $/ = undef; eval { no warnings qw( unopened ); my $DATA_position = tell DATA; croak "'tell DATA' failed: Probably no __END__ or __DATA__ segment." if $DATA_position < 0; seek DATA, 0, 0 or croak "'seek DATA' failed: Probably no __END__ or __DATA__ segment."; $source = <DATA>; seek DATA, $DATA_position, 0 or croak # Must leave *DATA usable. "seek to reset DATA filehandle failed after read."; }; if ($@) { croak $@ if $@ =~ /reset/; # Unstable state: Shouldn't be possible. eval { require FindBin; no warnings 'once'; open my $source_fh, $FindBin::Bin . '/' . $0 or croak $!; $source = <$source_fh>; }; croak "Couldn't read source file from *DATA or \$0: $@" if $@; } return $source; } }; print read_source(), "\n";
Этот фрагмент сначала пытается прочитать из
DATA
, что устраняет необходимость загружать FindBin и открывать новый дескриптор файла. Если это не удается,то он пробует подход FindBin. Если оба не удается, он создает исключение. Конечное успешное состояние хлебает весь источник файл в$source_code
. ДескрипторDATA
также будет восстановлен в том же состоянии, в котором он находился до вызова этого фрагмента.Это должно надежно решить вопрос о том, как читать исходный файл, не прибегая к фильтру источника.
Вы видите это в отладчике perl? Вот, вероятно, откуда берутся эти записи таблицы символов: см.
DATA STRUCTURES MAINTAINED BY CORE
раздел perldoc в вашем файлеperl5db.pl
.Единственный способ, который я вижу, чтобы получить запись
_<-
в таблице символов, - это запустить perl только с помощью переключателя-d
, а затем ввести программу Perl в стандартный ввод, например:$ perl -d Loading DB routines from perl5db.pl version 1.32 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. print "Hello world\n"; <Ctrl-D> main::(-:1): print "Hello world\n"; DB<1>
Отсюда,
@{"_<-"}
(или@{$main::{"_<-"}}
) содержит ваши входные данные,${"_<-"}
или${$main::{"_<-"}}
содержит " имя " вашего файла (просто-
), и%{"_<-"}
/%{$main::{"_<-"}}
содержит информацию о точках останова и действиях для пошагового выполнения кода из стандартного ввода.Без
strict refs
, вы также можете просмотреть эти данные с чем-то вродеDB<6> $name="_<-" DB<7> p ${$name} - DB<8> p @{$name} BEGIN { require 'perl5db.pl' }; print "Hello world\n"; DB<9> p %{$name}
Для
_<-
(или для любых других_<...
символов не существует файла, связанного с записью таблицы символов.