问题描述
我在 Perl 中创建对象时遇到错误。我当前代码的一部分是这样的:
#!/usr/bin/perl
use Mail::SpamAssassin::Client;
use warnings;
use strict;
my $client = new Mail::SpamAssassin::Client({port => 783,host => 'localhost'});
my $message = '';
if(!$result) {
print "Cant process a message ! Error: " . $result;
}
因此,如果对象已正确创建,我将无法检查 $client 变量。 只有在调用方法 $client->process($message) 后,我只能检查 $result 变量 但这对我来说并不令人满意。 例如,如果 spammassassin 守护程序将脱机,那么我在终端中进行了通信:
无法创建与 spamd 守护程序的连接:连接被拒绝
解决方法
模块执行以下操作:
unless ($remote) {
print "Failed to create connection to spamd daemon: $!\n";
return;
}
ug.模块不应该这样做。更糟糕的是,它写入 STDOUT 而不是 STDERR!
...实际上,它写入默认文件句柄,通常 STDOUT,但这可以使用 select
更改。这为我们提供了一个解决方案。
use Scope::Guard qw( guard );
sub validate {
my ($client) = @_;
open(my $fh,">",$^O eq 'Win32' ? 'nul' : '/dev/null')
or die $!;
my $old_fh = select($fh);
my $guard = guard { select($old_fh); };
return $client->ping();
}
my $rv = eval { validate($client) };
die($@) if $@;
die($!) if !$rv;
执行 ping 请求并返回并检查响应。如果你想检查创建连接而不是别的,你可以使用
use Scope::Guard qw( guard );
sub validate {
my ($client) = @_;
open(my $fh,$^O eq 'Win32' ? 'nul' : '/dev/null')
or die $!;
my $old_fh = select($fh);
my $guard = guard { select($old_fh); };
return !!$client->_create_connection();
}
validate($client)
or die($!);
请注意,模块会为每个方法调用创建一个新连接,因此检查可能通过,但稍后调用可能会失败(例如,由于网络问题)。