2011-09-07 12 views
9

Non proprio conoscendo Perl, ho migliorato uno script Perl con l'aiuto di un motore di ricerca amichevole.Esiste un modo più pulito per "uscire" condizionatamente da questo ciclo Perl?

trovo che ho bisogno di uscire da un ciclo while impostazione di un flag se la condizione si avvera:

foreach my $element (@array) { 
    if($costlyCondition) { 
     $flag = 1; 
     last; 
    } 
} 

So che il modo più bello di usare 'ultima' è qualcosa di simile:

foreach my $element (@array) { 
    last if ($costlyCondition); 
} 

Naturalmente, questo significa che mentre posso godere lo zucchero sintattico, non riesco a impostare la mia bandiera all'interno del ciclo, il che significa che ho bisogno di valutare $costlyCondition ancora una volta al di fuori.

C'è un modo più pulito per fare questo?

+6

postfix 'if' in realtà è solo per una dichiarazione. Il tuo primo è preferibile per più affermazioni su un condizionale. –

+0

Penso che un blocco if sia l'opzione migliore in questo caso. Il solito argomento per condizionali postfix sui controlli di loop è che posiziona il codice più significativo a sinistra. Sottolineando che il ciclo ha più condizioni di uscita rispetto a quelle condizioni di uscita. In questo caso, se usi alcune espressioni composte, il risultato nasconde semplicemente il controllo del loop più in profondità nell'espressione, rendendo più difficile vedere a colpo d'occhio. –

+0

@Joel: hai ragione. Rimango con la versione originale. – ArjunShankar

risposta

21

È possibile utilizzare un do {...} blocco:

do {$flag = 1; last} if $costlyCondition 

è possibile utilizzare l'operatore , per unire le dichiarazioni:

$flag = 1, last if $costlyCondition; 

si può fare lo stesso con la logica Operatore &&:

(($flag = 1) && last) if $costlyCondition; 

o addirittura la priorità più bassa and:

(($flag = 1) and last) if $costlyCondition; 

alla fine della giornata, non c'è alcun motivo reale per fare uno di questi. Fanno tutti esattamente come il tuo codice originale. Se il tuo codice originale funziona ed è leggibile, lascialo come è.

+0

Aggiungi '$ flag = 1 e last if $ costlyCondition;' al tuo strumento-shelf. –

+0

nel secondo esempio, rilascia {}. Non sono necessari – ysth

+0

Imparo un nuovo costrutto perl! (fare). Grazie! E come te e quasi tutti hanno detto, è meglio mantenere il codice così com'è. – ArjunShankar

5

Un pensiero è eseguire il ciclo in una subroutine che restituisce valori diversi in base al punto di uscita.

my $flag = check_elements(\@array); 

# later... 

sub check_elements { 
    my $arrayref = shift; 
    for my $ele (@$arrayref) { 
    return 1 if $costly_condition; 
    } 
    return 0; 
} 
7

Sono d'accordo con Nathan, che mentre il codice cercando pulito è pulito, a volte una versione leggibile è meglio. Solo per il gusto di farlo, però, ecco una versione orribile:

last if $flag = $costly_condition; 

Nota l'uso di assegnazione = invece di uguaglianza ==. Il compito restituirà qualunque valore sia in $costly_condition.

Questo ovviamente non renderà $flag = 1, ma qualunque sia lo $costly_condition. Ma, dal momento che deve essere vero, lo sarà anche $flag. Per ovviare a questo, si può - come Zaid menzionati nelle osservazioni - uso:

last if $flag = !! $costly_condition; 

Come accennato, soluzioni abbastanza orribile, ma lo fanno lavorare.

+4

'ultimo se $ flag = !! $ costly_condition; 'farebbe il trucco;) – Zaid

+0

@zaid Hehe, sì, l'ho visto anche io. – TLP

+0

per renderlo ancora peggio: 'ultimo a meno $ flag =! $ costly_condition';) – pavel

0

Questo è possibile, ma altamente sconsigliato: tali trucchi riducono la leggibilità del codice.

foreach my $element (@array) { 
    $flag = 1 and last if $costlyCondition; 
} 
Problemi correlati