3

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

#!/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;

与文件1:

key1    11
key2    22
key3    33

和文件2:

key1    11
key2    AB
key3    33

如果没有eval-block,程序会按预期运行:如果file2缺少 eg,则会发生错误并退出 Perl。使用eval-block 会发生正确的匹配,我只得到!!! 输入文件特定行上的错误关键字错误(如果输入文件完全丢失,我会得到每一行的错误)。但我不能使用$@. 这会为每一行创建错误。

我也尝试使用closeopen不使用die,但这也不起作用。

任何帮助表示赞赏!

4

1 回答 1

4

问题是你在eval块中返回值。

就像子程序一样, 的返回值eval是里面最后一行的值,或者是你在最后一行之前返回的值,使用return. 所以,如果你在eval块中返回值,你将它传递给parse子程序,但你没有将它返回给out子程序。这就是为什么$ok总是undef.

考虑这段代码:</p>

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子程序的值。

于 2013-09-25T09:14:19.357 回答