7

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'
    };
4

2 に答える 2

2

これは perl デバッガーで見ていますか? これらのシンボル テーブル エントリがどこから来ている可能性があります:ファイルDATA STRUCTURES MAINTAINED BY COREの perldoc のセクションをperl5db.pl参照してください。

_<-シンボル テーブルのエントリを取得する唯一の方法は、-dスイッチだけで perl を起動し、次に 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}

_<-(または他のシンボルの)シンボル テーブル エントリに関連付けられたファイルハンドルはありません_<...

于 2012-08-03T22:48:23.827 に答える
2

または、入力ソースを読みたい場合、ソース フィルターを使用する必要がありますか?

ソースファイルに__END__or__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__

このスクリプトは実行され ('Just another Perl hacker' と出力)、独自のソースを出力して終了します。

上記のコードでは、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ハンドルも、このスニペットを呼び出す前と同じ状態に復元されます。

これにより、ソース フィルターに頼らずにソース ファイルを読み取る方法の問題が確実に処理されるはずです。

于 2012-08-04T01:21:21.290 に答える