您需要使用的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 –