perl:assign array = smth它将返回false

时间:2013-04-12 18:36:52

标签: perl

我有以下声明:

my $iii=0;
while (my @row = sub_undef()) { print $iii++."\n"; }

sub sub_undef {

  if ($error) {
    return "something that will end the while loop";
  } else {
    return 1;
  }
}

在sub_undef()中,当我需要返回一些将在循环结束时返回的内容时,我可以有一个case(错误)。 任何想法怎么做?

- 梅德

4 个答案:

答案 0 :(得分:5)

在布尔上下文中,空数组为false 1

return () if $error;

方便的是,这是return默认的内容,如果你没有指定参数,那么你甚至可以写:

return if $error;

1)这里的一个微妙之处是空的数组在标量上下文中计算为0(即它的长度),而空列表评估为undef

@a = (); $b = @a;  # now $b is 0
$b = ();           # now $b is undef

但是,由于0和undef在布尔上下文中都是假的,因此这里的差异并不重要。有关详细信息,请参阅perldata


编辑:如果您需要区分错误条件而不仅仅是用完数据,那么raise an exception使用die进行错误可能会更好,并为结束返回一个空列表-数据的。然后你的循环看起来像这样:

eval {
    while (my @row = sub_undef()) { 
        # do something with @row
    }
};
if ($@) {
    # oops, we got an error, handle it
}

或使用Try::Tiny

try {
    while (my @row = sub_undef()) { 
        # do something with @row
    }
} catch {
    # oops, we got an error, handle it
};

答案 1 :(得分:4)

有几种方法:

解决方案1:如果你不需要返回一行,只需返回一个假标量:

sub sub_undef {
    # xxx
    return $error; # Already a true/false scalar
}
while (sub_undef()) { do_stuff(); }

解决方案2:返回一个arrayref而不是一个数组,如果发生错误则返回false(undef)

sub sub_undef {
    # xxx
    return $error ? undef : $rowArrayRef;
}
while (my $row = sub_undef()) { do_stuff(@$row); }

解决方案3:返回一个元组($ status,$ rowArrayRef)

sub sub_undef {
    # xxx
    return ($error, $rowArrayRef);
}
while (my ($error, $row) = sub_undef()) { last if $error; do_stuff(@$row); }

解决方案4:仅当行不能为空时才有效,除非根据您的业务案例发生错误!

sub sub_undef {
    # xxx
    return $error ? () : @row;
}
while (my @row = sub_undef()) { do_stuff(@row); }

解决方案5:使用异常进行错误处理(Try::Tiny

# No example worth bothering that won't be covered by Synopsis of the module

答案 2 :(得分:2)

return 1似乎表明你真的想要返回一个标量。如果您按如下方式编写循环

while (my ($value) = iter()) {
   ...
}

然后你可以发出三种状态信号:

  • return $value;成功返回。由于my ($value)中的parens,您甚至可以安全地返回错误或未定义的内容,而不会导致循环退出。

  • 当你的迭代器已经用尽时,
  • return;。这将导致执行在循环后继续。

  • die "message"发出错误信号。这将导致程序结束,除非使用eval BLOCK来捕获异常。

答案 3 :(得分:1)

空列表的分配将评估为false。

  if ($error) {
    return ();
  } else {
    return 1;
  }