我可以得到一个处理
它看起来有一个名为'_<-'
(不带引号)的主符号,与其他看起来可以处理的内容相同: '_</usr/perl/lib/Carp.pm'
, 例如。
有什么方法可以使用它?
或者如果我希望读取输入源,我是否必须使用源代码过滤器?
在回答暴徒:我不知道调试将打开的地方。 在转储出基表之后,%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'
};
或者如果我希望读取输入源,我是否必须使用源代码过滤器?
如果源文件具有__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
读取DATA
,这消除了加载FindBin并打开新文件句柄的需要。 如果失败了,那么它会尝试FindBin方法。 如果两者均失败,则会引发异常。 最终的成功状态将整个源文件拖入$source_code
。 DATA
句柄也将被恢复到它在调用此片段之前的相同状态。
这应该强有力地处理如何阅读源文件而不诉诸源代码过滤器的问题。
你在perl调试器中看到了这个吗? 这些符号表条目可能来自以下位置:请参阅perl5db.pl
文件中perldoc的DATA STRUCTURES MAINTAINED BY CORE
部分DATA STRUCTURES MAINTAINED BY CORE
的DATA STRUCTURES MAINTAINED BY CORE
部分。
我可以看到在符号表中获得_<-
条目的唯一方法是使用-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 worldn";
<Ctrl-D>
main::(-:1): print "Hello worldn";
DB<1>
从这里, @{"_<-"}
(或@{$main::{"_<-"}}
)包含您的输入, ${"_<-"}
或${$main::{"_<-"}}
包含文件的”名称“(只是-
), %{"_<-"}
/ %{$main::{"_<-"}}
包含关于步进的断点和动作的信息通过标准输入代码。
没有strict refs
,你也可以用类似的东西来查看这些数据
DB<6> $name="_<-"
DB<7> p ${$name}
-
DB<8> p @{$name}
BEGIN { require 'perl5db.pl' };
print "Hello worldn";
DB<9> p %{$name}
没有与_<-
(或其他任何_<...
符号)的符号表项关联的文件句柄。