在列表上下文中调用时,有没有办法区分从子例程返回的错误和空数组?

时间:2016-09-25 20:27:34

标签: perl

我有脚本:

#!/usr/bin/env perl

sub t0 {
    return;     # We return nothing for ERROR
}

sub t1 {
    @z =  ();
    return @z;  # We return array (which maybe empty) for no ERROR
}

在标量上下文中,我可以区分错误和OK状态:

my $x1 =  t0();  # undef
my $x2 =  t1();  # 0

在列表上下文中调用时,有没有办法区分从子例程返回的错误和空数组?

my @x1 =  t0();  # empty list
my @x2 =  t1();  # empty list

我觉得我需要“0E0”(零但是为真)但是对于列表上下文。

3 个答案:

答案 0 :(得分:6)

在这种情况下,在空列表和错误之间进行区分的方法是返回数组引用,例如

sub t0 {
    return undef;     # We return undef for ERROR
}

sub t1 {
    @z =  ();
    return \@z;  # We return array (which maybe empty) for no ERROR
}

所以基本上这些函数在列表上下文中的行为不同。它们总是返回一个标量,可能是undef,表示错误,或者返回对数组的引用。

答案 1 :(得分:4)

没有

如果成功(调用者必须取消引用)返回数组引用,并在失败时返回undef。

或者在失败时抛出异常(调用代码可以捕获)。

答案 2 :(得分:1)

在列表上下文中,子将返回列表,即使它只有一个元素undef。如果您必须在平面列表中返回数据 - 如果无法更改调用者,例如在大型代码库中 - 您可以die出错,eval位于顶层。 (因为die是一个例外,#34;起泡。")

平面列表的另一个选项相当缺乏吸引力,它仍然需要更改呼叫者。您可以返回一个空列表或undef,然后进行相应的测试 - 但请参阅下面的评论。

sub test {  
    # set @z (but not with undef!), $error
    return undef if $error;
    return @z;
}

my @ret = test();

if (not @ret) {
    # empty list
} 
else {
    foreach my $elem (@ret) {
        if (not defined $elem) {
            warn "Undefined";
            last
        }
        # ...
    }
}

但是,正如ikegami所指出的,如果@z合法地(没有错误)分配undef,例如一个恰好未定义的变量,则此代码可以&#39告诉我们区别。因此,必须进一步改变该功能以处理该问题。