문제

Perl 변수가 있습니다 $results 서비스에서 반환됩니다.값은 배열이어야 하며 $results 배열 참조여야 합니다.그러나 배열에 항목이 하나만 있는 경우에는 $results 해당 항목 하나를 포함하는 참조된 배열이 아니라 해당 값으로 설정됩니다.

나는하고 싶다 foreach 예상되는 배열을 반복합니다.확인하지 않고 ref($results) eq 'ARRAY', 다음과 동등한 것을 가질 수 있는 방법이 있습니까?

foreach my $result (@$results) {
    # Process $result
}

해당 특정 코드 샘플은 참조용으로는 작동하지만 단순 스칼라에는 문제가 있습니다.

편집하다:서비스에서 반환된 내용을 변경할 수 있는 방법이 없다는 점을 분명히 해야 합니다.문제는 값이 하나만 있으면 값이 스칼라가 되고 값이 두 개 이상 있으면 배열 참조가 된다는 것입니다.

도움이 되었습니까?

해결책

다음 외에 다른 방법이 있는지 잘 모르겠습니다.

$result = [ $result ]   if ref($result) ne 'ARRAY';  
foreach .....

다른 팁

또 다른 해결책은 서버에 대한 호출을 래핑하고 항상 배열을 반환하여 나머지 작업을 단순화하는 것입니다.

sub call_to_service
{
    my $returnValue = service::call();

    if (ref($returnValue) eq "ARRAY")
    {
        return($returnValue);
    }
    else
    {
       return( [$returnValue] );
    }
}

그러면 항목이 하나뿐이더라도 배열에 대한 참조를 다시 얻을 수 있다는 것을 항상 알 수 있습니다.

foreach my $item (@{call_to_service()})
{
  ...
}

뭐, 할 수 없다면...

for my $result ( ref $results eq 'ARRAY' ? @$results : $results ) {
    # Process result
}

아니면 이거...

for my $result ( ! ref $results ? $results : @$results ) {
    # Process result
}

그렇다면 이렇게 털이 많고 무서운 것을 시도해야 할 수도 있습니다!....

for my $result ( eval { @$results }, eval $results ) {
    # Process result
}

그리고 그 위험한 문자열 평가를 피하기 위해 그것은 정말 추악해집니다!!....

for my $result ( eval { $results->[0] } || $results, eval { @$results[1 .. $#{ $results }] } ) {
    # Process result
}

추신.내가 선호하는 것은 reatmon이 제공한 하위 call_to_service() 예제에서 이를 추상화하는 것입니다.

루프 내부의 코드를 리팩터링한 다음

if( ref $results eq 'ARRAY' ){
    my_sub($result) for my $result (@$results);
}else{
    my_sub($results);
}

물론 루프의 코드가 중요하지 않은 경우에만 그렇게 할 것입니다.

방금 이것을 테스트했습니다.

#!/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\n";
}
foreach my $r (@{testit()}){
   print $r." test2\n";
}

그리고 정상적으로 작동하는 것 같은데 서비스에서 결과가 반환되는 것과 관련이 있다고 생각합니까?반환 서비스를 제어할 수 없다면 해결하기 어려울 수 있습니다.

다음과 같이 할 수 있습니다:

my @some_array
push (@some_array, results);
foreach my $elt(@some_array){
  #do something
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top