我可以得到一个源 - 源?

时间:2012-08-03 20:14:40

标签: perl perl-io

看起来在main中有一个名为'_<-'的符号(没有引号)与看起来像的其他东西一样,它们可以处理:{{1}例如。

有没有办法使用它?

如果我希望阅读输入源,我是否必须使用源过滤器?


回复mob:我不知道Debug会在哪里打开。转出基表后,%INC的转储显示:

'_</usr/perl/lib/Carp.pm'

2 个答案:

答案 0 :(得分:2)

你在perl调试器中看到了这个吗?这些符号表条目可能来自:DATA STRUCTURES MAINTAINED BY CORE section of the perldoc in your perl5db.pl file

我能看到在符号表中获取_<-条目的唯一方法是仅使用-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}

没有与_<-(或任何其他_<...符号)的符号表条目相关联的文件句柄。

答案 1 :(得分: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__

此脚本将执行(打印'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句柄也将恢复到与之相同的状态。

这应该能够有力地处理如何在不使用源过滤器的情况下读取源文件的问题。