我正在使用Perl 5.16.3并遇到以下问题
我有使用以下代码读取Config :: General格式文件的代码:
use Config::General qw(ParseConfig);
my $meta_file = "/foo/bar/file";
my $hash;
eval {
$hash = {ParseConfig($meta_file)};
};
if ($@) {
print $@;
}
Run Code Online (Sandbox Code Playgroud)
现在,当文件指向buy $ meta_file出现问题时,此代码将失败,并且堆栈跟踪类似于以下内容:
在数字eq(==)中使用未初始化的值$ n_read Config :: General :: _ openfile_for_read('Config :: General = HASH(0xff92e30)','/ foo / bar / file')Config :: General :: _ open( 'Config :: General = HASH(0xff92e30)','/ foo / bar / file')Config :: General :: _ process('Config :: General = HASH(0xff92e30)')Config :: General :: new(' Config :: General','/ foo / bar / file')
有没有办法捕捉到这一点并继续执行我的代码?
中的代码eval似乎终止了程序,因此die初始化代码的触发必须已经转义。该模块使用Carp::Heavy了偶尔报告过异常行为的模块,这可能是造成问题的原因。模块来源中还引用了各种错误报告。
$SIG{__DIE__} = sub { say "Got: @_" };
Run Code Online (Sandbox Code Playgroud)
但这可能或可能不起作用。
最终的问题是为什么会这样。可以在源代码中跟踪报告的警告(其本身不会终止程序)
#尝试读取初始utf8字节顺序标记(BOM)
Run Code Online (Sandbox Code Playgroud)my $n_read = sysread $fh, my $read_BOM, length(_UTF8_BOM);
显然无法读取的内容,因为在下一行中$n_read仍未定义(“ 未初始化 ”)。sysread的undef返回指示错误。该常数定义为_UTF8_BOM
Run Code Online (Sandbox Code Playgroud)use constant _UTF8_BOM => "\x{ef}\x{bb}\x{bf}";
(由于有条件,:utf8仅在下面的几行中设置了图层,因此三个字符sysread)
因此,请检查文件的前几个字符。我试图混淆sysread(猜测之一是一个空字节),但无法重现该行为。一个空文件也可以正常工作。