28

$resultsサービスから返されるperl変数があります。値は配列であると想定されており$results、配列参照である必要があります。ただし、配列にアイテムが1つしかない場合は、$resultsその値に設定され、その1つのアイテムを含む参照配列には設定されません。

foreach期待される配列でループを実行したいと思います。チェックせずref($results) eq 'ARRAY'に、次のようなものを作成する方法はありますか?

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

その特定のコードサンプルは参照用に機能しますが、単純なスカラーについては文句を言います。

編集:サービスから返されるものを変更する方法がないことを明確にする必要があります。問題は、値が1つしかない場合は値がスカラーになり、複数の値がある場合は配列参照になることです。

4

6 に答える 6

26

他に方法があるかどうかわかりません:

$result = [ $result ]   if ref($result) ne 'ARRAY';  
foreach .....
于 2008-08-06T07:13:16.753 に答える
12

Another solution would be to wrap the call to the server and have it always return an array to simplify the rest of your life:

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

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

Then you can always know that you will get back a reference to an array, even if it was only one item.

foreach my $item (@{call_to_service()})
{
  ...
}
于 2008-08-19T14:16:57.493 に答える
2

まぁ出来ないなら…

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
}

PS。私の好みは、reatmon によって与えられた sub ala call_to_service() の例でそれを抽象化することです。

于 2008-10-12T21:14:12.530 に答える
0

ループ内のコードをリファクタリングしてから、

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

もちろん、私はループ内のコードが重要である場合にのみそれを行います。

于 2008-08-14T21:41:18.903 に答える
-1

私はこれを次のようにテストしました:

#!/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";
}

そして、それはうまくいくようです、それで私はそれがサービスから返される結果と関係があると思いますか?返品サービスを管理できない場合、これをクラックするのは難しいかもしれません

于 2008-08-06T06:22:23.080 に答える