您需要使用的eval
块形式,以防止程序时,将引发异常死亡。不幸的是,eval
的裸露使用充满了令人尴尬的角落案例,最好使用Try::Tiny
模块来处理这些模块。
为了在您的问题中达到您的代码目的,您可以编写类似这样的内容。显然,你将不得不为变量
重要的是要注意是try
和catch
是子程序是非常重要的供应有用的数据。这意味着在catch
之后你需要一个分号,并且你不能在catch
之内设置next
,因为你不能在子程序中做到这一点。您必须保留某种状态设置,以便后续代码可以执行必要的任何操作,在这种情况下,我只需检查$clients{$cur_client}
是否仍然存在 - 如果出现问题,它将被catch
例程删除
另外值得说明的是,die
字符串可在catch
例程中的$_
中使用,因此您可以检查失败原因。在这种情况下,catch
期望仅处理unrecognized key format
错误,所以代码检查确实是失败的原因。如果没有,那么它会发出另一种die $_
,以反映已发生未处理的错误
use strict;
use warnings 'all';
use Crypt::OpenSSL::RSA;
use Try::Tiny;
my %clients = (aa => {});
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;
for my $cur_client (keys %clients) {
try {
$clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
}
catch {
if (/unrecognized key format/) {
server_log("Bad key exchange, dropping user $address:$port...");
delete $clients{$cur_client};
}
else {
die $!;
}
};
next unless exists $clients{$cur_client};
# More handling of $cur_client in the case that
# the call to new_public_key succeeds
}
sub server_log {
print "Logging: $_[0]\n";
}
接受的答案首先提到'eval',之前建议'Try :: Tiny'是可取的,因为'eval'有许多陷阱可以陷入,'Try :: Tiny'避免它们。例如,如果'$ @'具有非真值,那么您的错误处理代码将无法检测到发生了错误。 https://metacpan.org/pod/Try::Tiny#might-not-be-a-true-value –