使用Config :: General解析错误文件时捕获问题

lea*_*ner 2 perl

我正在使用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')

有没有办法捕捉到这一点并继续执行我的代码?

zdi*_*dim 5

中的代码eval似乎终止了程序,因此die初始化代码的触发必须已经转义。该模块使用Carp::Heavy了偶尔报告过异常行为的模块,这可能是造成问题的原因。模块来源中还引用了各种错误报告。

您可以尝试通过一个钩子来控制它die

$SIG{__DIE__} = sub { say "Got: @_" };
Run Code Online (Sandbox Code Playgroud)

但这可能或可能不起作用。

最终的问题是为什么会这样。可以在源代码中跟踪报告的警告(其本身不会终止程序)

#尝试读取初始utf8字节顺序标记(BOM)

my $n_read  = sysread $fh, my $read_BOM, length(_UTF8_BOM);
Run Code Online (Sandbox Code Playgroud)

显然无法读取的内容,因为在下一行中$n_read仍未定义(“ 未初始化 ”)。sysreadundef返回指示错误。该常数定义为_UTF8_BOM

use constant _UTF8_BOM => "\x{ef}\x{bb}\x{bf}";
Run Code Online (Sandbox Code Playgroud)

(由于有条件,:utf8仅在下面的几行中设置了图层,因此三个字符sysread

因此,请检查文件的前几个字符。我试图混淆sysread(猜测之一是一个空字节),但无法重现该行为。一个空文件也可以正常工作。