人为的例子:
use strict;
use warnings;
my $myval = 'a';
my @result = my_sub($myval);
if (@result) {
print "DEFINED\n";
}
my ($res1, $res2, $res3) = @result;
print "res1=$res1, res2=$res2, res3=$res3\n";
sub my_sub {
my $myval = shift;
if ($myval eq 'a') {
return undef;
}
return ("a","b","c");
}
如何检查sub是否返回undef?
或
如何检查sub是否未返回undef?
答案 0 :(得分:4)
return undef
返回一个元素的列表,即undef
。
@result = my_sub($myval);
if (@result == 1 && !defined($result[0])) {
warn "my_sub() returned undef";
} else {
print "my_sub() returned data\n";
}
也就是说,带有一个undef
元素的列表几乎从来都不是您想要的。请参见How do I return nothing from a subroutine?,您通常只想return
不带参数。在标量上下文中,它返回undef
,在列表上下文中,它返回一个空列表。
sub my_other_sub {
my $myval = shift;
if ($myval eq 'a') {
return;
}
return ("a","b","c");
}
...
@result = my_other_sub($arg1);
$result = my_other_sub($arg2);
if (@result == 0) { # or: if (!@result) ... or: unless (@result) ...
warn "my_other_sub(arg1) did not return any data";
} else {
print "my_other_sub(arg1) returned data\n";
}
if (!defined($result)) {
warn "my_other_sub(arg2) did not return any data";
} else {
print "my_other_sub(arg2) returned data\n";
}
答案 1 :(得分:2)
与其他人一样,我建议使用element.all(by.css('#paragraphList table tbody tr'))
或更明确的let allRows = element.all(by.css(`#paragraphList table tbody tr`)); //will have all the rows.
allRows.then((rowsResolved) => {
// now have all the rows
PO.populateData(rowsResolved).then((allData) => {console.log(allData)}) // should be an Array od arrays, each array would be containing texts from all the cells.
// Considering you have a Page Object and added the functions below in the Page Object.
// Page Object is nothing but another class where we keep our utility methods
})
// driving function
populateData(rowsResolved) {
let data = [];
return this._populateRows(0, rowsResolved, data);
}
// calls itself recursively to loop over the rows
private _populateRows(index, rowsResolved, data) {
if (index >= rowsResolved.length) {
let defer = protractor.promise.defer();
defer.fulfill(data);
return defer.promise; // so that it is chainable even if I don't have any rows
}
let cells = element.all(by.css(`#paragraphList table tbody tr:nth-child(${index + 1}) td`));
cells.then((cellsResolved) => {
let cellData = [];
if (cellsResolved.length) {
data.push(cellData);
}
this._populateCells(0, cellsResolved, cellData);
return this._populateRows(index + 1, rowsResolved, data);
})
}
// calls itself recursively to loop over all the cells ofeach row.
private _populateCells(index, cellsResolved, cellData) {
if (index >= cellsResolved.length) {
let defer = protractor.promise.defer();
defer.fulfill(cellData);
return defer.promise; // so that it is chainable even if I don't have any cells(that would be an incorrect structure though, if a row exists then cells have to exist )
}
cellsResolved[index].getText().then((cellValue) => {
cellData.push(cellValue)
});
return this._populateCells(index + 1, cellsResolved, cellData);
}
。这将返回一个空列表。但是,由于该示例是人为设计的,因此我们无法确定空列表不是有效的返回值。如果这是有效的回报,或者合理地说是一天,那么您还有其他选择,IMO不太理想,但是可以更灵活。
一个很明显的方法是使用return
,正如zdim所建议的那样,但是这种方法比较笨拙。实际上可能确实是您想要的-如果这种情况确实不应该发生,那么die就是完美的选择,因为如果不将失败包装在return ()
中,它可能会导致程序中止。
另一种选择是让您的子返回数组引用而不是列表。然后,您可以直接返回die
,您的呼叫者就可以很容易地检查到这一点:eval
。该数组的其他用途仅需要进行解除引用,例如undef
。当简单的my $result = my_sub(...);
无法满足要求时,这可能是我的偏爱。值得一提的是,只有引用被传回,而不是整个列表。即使空列表无效但列表可能很大,也可以考虑这样做。
其他选项也很多,尽管这些选项可能是最简单的。例如,您可以返回一个哈希(或数组),其中一个条目指示成功/失败,另一个则指示该数组。您可以将成功/失败作为第一个元素返回(您想做的示例将是my ($res1, $res2, $res3) = @$result;
,然后将第一个元素移开以查看它是否成功)。您可以将返回值嵌入封装了所有内容的对象中。在这些对象中,只有我会认真考虑的对象,但这在很大程度上取决于体系结构的其余部分,并且非常少见。
答案 2 :(得分:0)
子例程在您使用的列表上下文中返回标量列表,然后将其分配给变量。因此,如果您从中返回undef
,则$res
变量将是undef
-首先分配undef
,而其他变量未分配(而数组@result
将有一个元素undef
)
perl -Mstrict -wE'
my $val = shift;
sub t { return undef if shift eq "bad"; return qw(a b) };
my ($v1, $v2) = t($val);
if (not defined $v1 and not defined $v2) { say "undef" }
else { say "$v1, $v2" }
' bad
第一个shift
取下@ARGV
的值,因此请更改“ 坏”的输入以查看其他情况。如果我们知道如何使用它,可以用更紧凑,更清晰的方式编写。
我很欣赏这是一个测试示例,但是它仍然太复杂了,允许出现棘手的情况。例如,您的第一种情况将不起作用,因为@result
是 not“ false” (空列表),代码对其进行测试,因为它确实包含一个元素,即{{ 1}}。
对于这种“特殊”返回,在您认为特殊的情况下,可以使用不带任何参数的return或抛出一个die。有关上下文感知的返回,请参见wantarray。