我的目的是检查关键字(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;
with file1:
key1 11
key2 22
key3 33
和file2:
key1 11
key2 AB
key3 33
没有eval
- 阻止程序按预期运行:例如缺少file2
,发生错误并且Perl退出。使用eval
- 阻止正确的匹配发生,我只得到 !!!对于输入文件的特定行上的错误,关键字出错(如果输入文件完全未命中,则每行都会出错)。但我无法使用$@
。这会为每一行创建错误。
我还尝试使用close
或open
而不使用die
,但这两种方法都不起作用。
感谢任何帮助!
答案 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
子例程。