我有一个从服务返回的perl变量$results。 该值应该是一个数组,而$results应该是一个数组引用。 但是,当数组中只有一项时,$results将设置为该值,而不是包含该项的引用数组。
我想对期望的数组做一个foreach循环。 不检查ref($results) eq 'ARRAY',是否有任何等同于以下内容的方法:
1 2 3
| foreach my $result (@$results) {
# Process $result
} |
那个特定的代码示例可以用作参考,但是会抱怨简单的标量。
编辑:我应该澄清,我没有办法更改从服务返回的内容。 问题在于,当只有一个值时,该值将为标量;而当存在多个值时,该值将为数组引用。
我不确定除了以下以外还有其他方法:
1 2
| $result = [ $result ] if ref($result) ne 'ARRAY';
foreach ..... |
另一个解决方案是将调用包装到服务器,并使其始终返回一个数组以简化您的余生:
1 2 3 4 5 6 7 8 9 10 11 12 13
| sub call_to_service
{
my $returnValue = service::call();
if (ref($returnValue) eq"ARRAY")
{
return($returnValue);
}
else
{
return( [$returnValue] );
}
} |
这样,您始终可以知道您将获得对数组的引用,即使它只是一项。
1 2 3 4
| foreach my $item (@{call_to_service()})
{
...
} |
好吧,如果你做不到...
1 2 3
| for my $result ( ref $results eq 'ARRAY' ? @$results : $results ) {
# Process result
} |
或这个...
1 2 3
| for my $result ( ! ref $results ? $results : @$results ) {
# Process result
} |
那么您可能必须尝试一些像这样的令人毛骨悚然的东西!
1 2 3
| for my $result ( eval { @$results }, eval $results ) {
# Process result
} |
为了避免危险的字符串评估,它变得非常丑陋!
1 2 3
| for my $result ( eval { $results->[0] } || $results, eval { @$results[1 .. $#{ $results }] } ) {
# Process result
} |
PS。我的偏好是在reatmon提供的sub ala call_to_service()示例中将其抽象出来。
您可以这样做:
1 2 3 4 5
| my @some_array
push (@some_array, results);
foreach my $elt(@some_array){
#do something
} |
我将在循环内重构代码,然后执行
1 2 3 4 5
| if( ref $results eq 'ARRAY' ){
my_sub($result) for my $result (@$results);
}else{
my_sub($results);
} |
当然,只有在循环中的代码不平凡的情况下,我才会这样做。
我刚刚用以下方法进行了测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #!/usr/bin/perl -w
use strict;
sub testit {
my @ret = ();
if (shift){
push @ret,1;
push @ret,2;
push @ret,3;
}else{
push @ret,"oneonly";
}
return \\@ret;
}
foreach my $r (@{testit(1)}){
print $r." test1\
";
}
foreach my $r (@{testit()}){
print $r." test2\
";
} |
而且似乎工作正常,所以我认为这与从服务中返回结果有关吗?
如果您无法控制退货服务,那么可能很难破解