【发布时间】:2016-02-20 01:10:05
【问题描述】:
我已经用一个小模块包装了 Perl 的 Net::SSH::Expect,以减少编写用于我们的 HP iLO 卡的新配置脚本所需的样板代码。一方面我希望这个包装器尽可能精简,以便非程序员同事可以使用它,但我也希望它尽可能写得好。
它是这样使用的:
my $ilo = iLO->new(host => $host, password => $password);
$ilo->login;
$ilo->command("cd /system1");
$ilo->command("set oemhp_server_name=$system_name", 'status=0');
这是iLO::command():
sub command {
my ($self, $cmd, $response) = @_;
$response = 'hpiLO-> ' unless defined($response);
# $self->{ssh} is a Net::SSH::Expect object
croak "Not logged in!\n" unless ($self->{ssh});
$self->{ssh}->send($cmd);
if ($self->{ssh}->waitfor($response, $self->{CMD_TIMEOUT}, '-re')) {
return {
before => $self->{ssh}->before(),
match => $self->{ssh}->match(),
after => $self->{ssh}->after(),
};
} else {
carp "ERROR: '$cmd' response did not match /$response/:\n\n",
$self->{ssh}->before()),
"\n";
return undef;
}
}
我有两个相关的查询。首先,我应该如何处理与预期响应不匹配的响应?我想我现在正在做的事情是令人满意的——通过返回undef,我表示有些东西坏了,我的croak() 将输出一个错误(虽然很难优雅)。但这感觉就像是代码的味道。如果 Perl 有异常,我会提出一个异常并让调用代码决定是否忽略它/退出/打印警告,但它没有(嗯,在 5.8 中)。也许我应该返回一些带有错误消息和$ilo->before() 内容的其他对象(iLO::response 或其他对象)(这只是 Net::SSH::Expect 的before())?但如果我这样做——并且必须将每个 $ilo->command 包装在一个测试中以捕获它——我的脚本将再次充满样板。
其次,我应该为成功返回什么?同样,我的散列或多或少包含来自 Net::SSH::Expect 的响应,但它在某种程度上感觉不“正确”。虽然这个例子是用 Perl 编写的,但我用其他语言编写的代码发出了同样熟悉的气味:我从不知道如何或从方法返回什么。你能告诉我什么?
【问题讨论】:
-
你永远不应该
return undef(),因为这会在列表上下文中创建一个单元素列表。只要return;在任何情况下都会做正确的事情。 :)
标签: perl language-agnostic error-handling