使用`$ @`进行错误处理

时间:2013-09-25 08:44:45

标签: perl error-handling eval

我的目的是检查关键字(file1file2key1)的几个输入文件(key2key3)并匹配一个数字。如果发生错误,程序不应该停止并检查下一个单词/文件。我想给出足够的错误输出。 到目前为止我的代码是:

#!/usr/bin/perl
use strict;
use warnings;

foreach ("key1","key2","key3"){output("$_","file1")}
foreach ("key1","key2","key3"){output("$_","file2")}
foreach ("key1","key2","key3"){output("$_","file1")}

sub parse{

my $keyword = shift;
my $path = shift;
my $match;

eval{
        open(FILE,"$path") or die "Cannot open file $path in parse(): $!\n";
        while (my $line = <FILE>) {
                if ($line =~ /^$keyword\s+(\d+)/){ ;
                        $match = $1;
                }
        }
        return (1, $match) if (defined $match);
        return (0)
    };
if ($@){print "!!! Error in parse():\n\t $@\n";}    
}

sub output{

my $keyword = shift;
my $path = shift;
my ($ok, $tmp);

($ok, $tmp) = parse("$keyword", "$path");
print "Value $tmp for keyword: $keyword\n" if $ok;
print "!!! Error for keyword: $keyword\n" if not $ok;

}

1;

with file1:

key1    11
key2    22
key3    33

和file2:

key1    11
key2    AB
key3    33

没有eval - 阻止程序按预期运行:例如缺少file2,发生错误并且Perl退出。使用eval - 阻止正确的匹配发生,我只得到 !!!对于输入文件的特定行上的错误,关键字出错(如果输入文件完全未命中,则每行都会出错)。但我无法使用$@。这会为每一行创建错误。

我还尝试使用closeopen而不使用die,但这两种方法都不起作用。

感谢任何帮助!

1 个答案:

答案 0 :(得分:4)

问题是你在eval阻止中返回值。

就像子程序一样,eval的返回值是最后一行的值,或者是使用return在最后一行之前返回的值。因此,如果您在eval块中返回值,则将其传递给parse子例程,但您没有将其返回到out子例程。这就是为什么$ok总是undef

考虑这段代码:

my $ret = eval{
        open(FILE,"$path") or die "Cannot open file $path in parse(): $!\n";
        #open(FILE,"$path");
        while (my $line = <FILE>) {
                if ($line =~ /^$keyword\s+(\d+)/){ ;
                        $match = $1;
                }
        }
        return (1) if (defined $match);
        return (0);
        #close(FILE);

};
print "$ret\n";

如果文件匹配,您将看到1。但是仍然应该将从eval阻止传递的值返回到out子例程。