当前位置:  开发笔记 > 编程语言 > 正文

我应该如何处理Perl方法中的错误,以及从方法中返回什么?

如何解决《我应该如何处理Perl方法中的错误,以及从方法中返回什么?》经验,为你挑选了2个好方法。

我用一个小模块包装了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::response带有错误信息的对象(或其他东西)和$ilo->before()(只是Net :: SSH :: Expect's before())的内容?但是,如果我这样做 - 并且必须将每个人都包裹$ilo->command在测试中以便捕获它 - 我的脚本将再次充满样板.

其次,我应该回归什么才能获得成功?同样,我的哈希包含来自Net :: SSH :: Expect的响应或多或少可以完成工作,但它不会以某种方式感觉"正确".虽然这个例子在Perl我的代码在其他语言中发出了同样熟悉的气味:我从来不知道如何或从一个方法返回什么.你能告诉我什么?



1> Andru Luvisi..:

在Perl中引发异常的常用方法是使用die.通常的办法赶上他们使用的eval与块作为参数,和EVAL完成后测试$ @.



2> friedo..:

如果你熟悉的,如Java语言异常,然后想die作为throweval作为trycatch.而不是返回undef,你可以做这样的事情:

if ($self->{ssh}->waitfor($response, $self->{CMD_TIMEOUT}, '-re')) {
    return {
        before => $self->{ssh}->before(),
        match => $self->{ssh}->match(),
        after => $self->{ssh}->after(),
    };
}

die "ERROR: '$cmd' response did not match /$response/:\n\n" 
. $self->{ssh}->before();

然后,在您的调用代码中:

eval { 
    $ilo->command("set oemhp_server_name=$system_name", 'status=0');
};

if ( my $error = $@ ) { 
    # handle $error here
}

就像其他语言中的异常一样,这允许您在任何时候摆脱子方法,而不必担心在调用堆栈中传播返回值.它们将被eval发现它们的第一个块捕获.此外,您可以die再次重新抛出一个无法处理备份的异常.

更好的是,您可以使用die抛出一个对象,您的异常处理程序可以查询该对象以获取有用的信息和错误消息.我喜欢为此目的使用Exception :: Class.该错误模块提供了这样做类似Java的try/catch块,还有一些语法糖.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有