Могу ли я получить ручку к источнику?
Похоже, в главном есть символ '_<-'
(без кавычек) таким же образом, как и другие вещи, которые выглядят так, как будто они могут быть ручками: '_</usr/perl/lib/Carp.pm'
, например.
Есть ли способ использовать это?
Или мне придется использовать фильтр источника, если я надеюсь прочитать источник ввода?
В ответ мобу: я не знаю, куда включится 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
handle также будет восстановлен в том же состоянии, в котором он находился до вызова этого фрагмента.
Это должно решительно решить вопрос о том, как читать исходный файл, не прибегая к исходному фильтру.
Вы видите это в отладчике 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}
Нет никакого дескриптора файла, связанного с записью таблицы символов для _<-
(или для любого другого _<...
символы).