Μπορείτε να αναγκάσει είτε ένα βαθμωτό ή συστοιχία διαιτητή να είναι ένας πίνακας σε Perl;

ψήφοι
25

Έχω μια μεταβλητή perl $resultsπου παίρνει επέστρεψε από μια υπηρεσία. Η τιμή υποτίθεται ότι είναι ένας πίνακας, και $resultsπρέπει να είναι μια αναφορά σειρά. Ωστόσο, όταν ο πίνακας έχει μόνο ένα στοιχείο σε αυτό, $resultsθα πρέπει να οριστεί σε αυτή την τιμή, και όχι μια αναφορά πίνακα που περιέχει αυτό ένα στοιχείο.

Θέλω να κάνω μια foreachθηλιά για την αναμενόμενη σειρά. Χωρίς έλεγχο ref($results) eq 'ARRAY', υπάρχει κάποιος τρόπος για να έχουν κάτι αντίστοιχο με το ακόλουθο εκεί:

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

Αυτό συγκεκριμένο δείγμα κώδικα θα εργαστεί για την αναφορά, αλλά θα διαμαρτύρονται για τον απλό βαθμωτό.

EDIT: Θα πρέπει να διευκρινιστεί ότι δεν υπάρχει κανένας τρόπος για μένα να αλλάξει ό, τι επιστρέφεται από την υπηρεσία. Το πρόβλημα είναι ότι η τιμή θα είναι ένα βαθμωτό όταν υπάρχει μόνο μία αξία και θα είναι μια αναφορά σειρά, όταν υπάρχουν περισσότερες από μία τιμές.

Δημοσιεύθηκε 06/08/2008 στις 06:56
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
26

im δεν είναι σίγουρος ότι υπάρχει κάποιος άλλος τρόπος από:

$result = [ $result ]   if ref($result) ne 'ARRAY';  
foreach .....
Απαντήθηκε 06/08/2008 στις 08:13
πηγή χρήστη

ψήφοι
12

Μια άλλη λύση θα ήταν να τυλίξετε την κλήση στον server και να έχουν πάντα επιστρέψει έναν πίνακα για να απλοποιήσει το υπόλοιπο της ζωής σας:

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

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

Στη συνέχεια, μπορείτε πάντα να ξέρετε ότι θα πάρετε πίσω μια αναφορά σε μια σειρά, ακόμα κι αν ήταν μόνο ένα στοιχείο.

foreach my $item (@{call_to_service()})
{
  ...
}
Απαντήθηκε 19/08/2008 στις 15:16
πηγή χρήστη

ψήφοι
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
}

και να αποφευχθεί η επικίνδυνη κορδόνι eval γίνεται πραγματικά άσχημο fugly !! ....

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

PS. Η προτίμησή μου θα ήταν να αφηρημένη μακριά σε επιμέρους ala call_to_service () παράδειγμα που δίνεται από reatmon.

Απαντήθηκε 12/10/2008 στις 22:14
πηγή χρήστη

ψήφοι
0

Μπορείτε να το κάνετε ως εξής:

my @some_array
push (@some_array, results);
foreach my $elt(@some_array){
  #do something
}
Απαντήθηκε 23/11/2016 στις 05:34
πηγή χρήστη

ψήφοι
0

Θα ήθελα εκ νέου παράγοντα τον κωδικό στο εσωτερικό του βρόχου και στη συνέχεια, κάντε

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

Φυσικά θα ήθελα να κάνω μόνο ότι αν ο κώδικας στο βρόχο ήταν μη-τετριμμένη.

Απαντήθηκε 14/08/2008 στις 22:41
πηγή χρήστη

ψήφοι
0

Έχω μόνο δοκιμαστεί αυτό με:

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

Και φαίνεται να δουλεύει εντάξει, έτσι σκέφτομαι ότι έχει να κάνει με το αποτέλεσμα να πάρει επέστρεψε από την υπηρεσία; Αν δεν έχετε κανέναν έλεγχο πάνω από την επιστροφή υπηρεσία αυτή μπορεί να είναι δύσκολο σε κάποιον να σπάσει

Απαντήθηκε 06/08/2008 στις 07:22
πηγή χρήστη

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