Могу ли я получить ручку к источнику?

Похоже, в главном есть символ '_<-' (без кавычек) таким же образом, как и другие вещи, которые выглядят так, как будто они могут быть ручками: '_</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}

Нет никакого дескриптора файла, связанного с записью таблицы символов для _<- (или для любого другого _<... символы).

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