Můžete vynutit buď skalární nebo pole ref být pole v Perlu?

hlasů
25

Mám perl proměnnou $results, který se vrátil z službu. Hodnota má být pole, a $resultsby měl být referenčním polem. Nicméně, když pole má pouze jednu položku v něm, $resultsbude nastaven na tuto hodnotu, a to odkazované pole, které obsahuje tuto jednu položku.

Chci udělat foreachsmyčku na očekávané pole. Bez kontroly ref($results) eq 'ARRAY', je tam nějaký způsob, jak mít něco, co odpovídá následující:

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

Že zejména ukázkový kód bude fungovat jako referenční, ale bude si stěžovat na jednoduché skalární.

EDIT: Měl bych upřesnit, že neexistuje žádný způsob, jak pro mě změnit to, co se vrátil ze služby. Problém je v tom, že hodnota bude skalární, když je pouze jedna hodnota, a bude to referenční pole, pokud existuje více než jedna hodnota.

Položena 06/08/2008 v 06:56
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
26

im ne jistý, že je to nějaký jiný způsob, než:

$result = [ $result ]   if ref($result) ne 'ARRAY';  
foreach .....
Odpovězeno 06/08/2008 v 08:13
zdroj uživatelem

hlasů
12

Dalším řešením by bylo zabalit volání na server a mít vždy vrátit matici zjednodušit zbytek svého života:

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

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

Pak můžete vždy vědět, že dostanete zpět odkaz na pole, i kdyby to byla jen jedna položka.

foreach my $item (@{call_to_service()})
{
  ...
}
Odpovězeno 19/08/2008 v 15:16
zdroj uživatelem

hlasů
2

No, pokud nemůžete dělat ...

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

nebo toto...

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

pak možná budete muset zkusit něco chlupatý strašidelné takhle! ....

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

a zabránit tomu, aby nebezpečný řetězec eval se stává opravdu ošklivý fugly !! ....

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

PS. Moje preference by bylo abstraktní to pryč sub ala call_to_service () například dána reatmon.

Odpovězeno 12/10/2008 v 22:14
zdroj uživatelem

hlasů
0

Můžete to udělat takto:

my @some_array
push (@some_array, results);
foreach my $elt(@some_array){
  #do something
}
Odpovězeno 23/11/2016 v 05:34
zdroj uživatelem

hlasů
0

Já bych re-faktor kód uvnitř smyčky a proveďte

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

Samozřejmě, že by to pouze to, že v případě, že kód ve smyčce byl non-triviální.

Odpovězeno 14/08/2008 v 22:41
zdroj uživatelem

hlasů
0

Právě jsem zkouší to s:

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

A zdá se, že funguje ok, takže si myslím, že to má co do činění s výsledkem stále se vrátil ze služby? Pokud nemáte kontrolu nad vracející službě to může být těžké, kdo bezva

Odpovězeno 06/08/2008 v 07:22
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more