2012-03-14 10 views
11

Ho una dichiarazionePerl una riga if

$set eq "Y" ? $set = "N" : $set = "Y"; 

Ma non importa ciò che si propone sempre di "N"

# Toggle setting 
if ($set eq "Y") 
{ 
    $set = "N"; 
} 
else 
{ 
    $set = "Y"; 
} 

Perché l'uno di linea non sembra funzionare?

+0

@ruakh: Sì, ma non lo cambia da ''Y'' a'' N''. –

+0

@ KeithThompson: Sì, hai ragione. L'OP ha detto che lo imposta sempre su "N", ma in realtà è vero esattamente l'opposto. – ruakh

+0

Oh sì, questo è vero. Ho dimenticato di scambiare le risposte con il loro originale. –

risposta

25

causa di regole di precedenza, Perl non è l'analisi la sua dichiarazione come si pensa :

$ perl -MO=Deparse,-p -e '$set eq "Y" ? $set = "N" : $set = "Y"' 
((($set eq 'Y') ? ($set = 'N') : $set) = 'Y'); 
-e syntax OK 

quindi, come si vede, in entrambe le condizioni, il risultato finale è lo scalare $set che poi viene impostato su Y.

È possibile risolvere il problema con un paio di parentesi:

$set eq "Y" ? $set = "N" : ($set = "Y") 

Ma perché ripetere l'assegnazione:

$set = $set eq 'Y' ? 'N' : 'Y'; 
+0

Grazie, per la spiegazione approfondita del mio cattivo Perl. Ho finito con un 'my $ set = ($ set eq 'Y'? 'N': 'Y');' come nella risposta di @ Keith. –

7
$set = ($set eq "Y") ? "N" : "Y"; 

dovrebbe funzionare

8

Precedenza degli operatori. Quello che hai scritto è equivalente a

($set eq "Y" ? $set = "N" : $set) = "Y"; 

Se ti ostini a scrivere tale codice stringato, questo ha più senso:

$set = ($set eq "Y" ? "N" : "Y"); 
5

Si tratta di precedenza; facciamolo l'intento con la parentesi, e poi lasciare che il Perl rimuovere di nuovo:

perl -MO=Deparse -e '($set eq "Y") ? ($set = "N") : ($set = "Y"); print $set' 
$set eq 'Y' ? $set = 'N' : ($set = 'Y'); 
print $set; 
-e syntax OK 

Qual è dunque la parenthesing necessario per fare come desiderato.

3

Se non si preferisce utilizzare istruzioni condizionali "C" di stile, si può fare la stessa cosa con 2 linee:

my $set = "Y"; #Set the scope and default value 
$set = "N" if ($set eq "Y"); 

io personalmente raccomando lo stile "C" descritto da altri di cui sopra ... facilmente dimostra le due opzioni che può essere una variabile.

Tuttavia, il metodo che mostro è ottimo quando si ha a che fare con un singolo risultato condizionale.

Problemi correlati