2015-03-27 11 views
7

Guardando la documentazione per Reading Excel, c'è una dichiarazione che non capisco davvero.cosa è || = in perl per?

Qualcuno può spiegare cosa fa $sheet -> {MaxRow} ||= $sheet -> {MinRow};?

Ho capito che è un operatore di assegnazione. Tuttavia non capisco come è stato pensato che lo || funzioni?

risposta

12
$sheet -> {MaxRow} ||= $sheet -> {MinRow}; 

è equivalente a:

$sheet -> {MaxRow} = ($sheet -> {MaxRow} || $sheet -> {MinRow}); 

Il locale operatore OR valuta il secondo operando solo se il primo è falso. Quindi, MaxRow otterrà il valore del MinRow se MaxRow è 0 (probabilmente la prima iterazione).

6

L'operatore ||= è logico-OR-assegna. È simile a +=, che è add-assign. Calcola l'OR logico di LHS e RHS, quindi assegna il risultato all'LHS, che pertanto deve essere un lvalue valido.

In altre parole, come

$a += 3; 

è equivalente a

$a = $a+3; 

possiamo dire che

$a ||= 1; 

è equivalente a

$a = $a||1; 

Ora, per quanto riguarda l'affermazione a cui si fa riferimento nella tua domanda, c'è un po 'più di là che nel mio esempio sopra. Nella tua dichiarazione, il LHS non è solo un semplice token variabile, ma è un token variabile che viene trattato come riferimento hash ($sheet) e viene sottoposto a dereferenziazione per ottenere il valore che è codificato con la stringa 'MaxRow'. L'RHS è anche un'operazione di dereferenziazione hash su $sheet, ma la cui chiave è 'MinRow'. Ma il comportamento è lo stesso; possiamo dire che

$sheet->{'MaxRow'} ||= $sheet->{'MinRow'}; 

è equivalente a

$sheet->{'MaxRow'} = $sheet->{'MaxRow'}||$sheet->{'MinRow'}; 

(Nota: mi piace sempre in modo esplicito preventivo hash valori chiave come stringhe, perché questo è quello che sono, ma non tutti vale per quel grado di esplicitazione.)

per di più la logica OR funzionamento, vedere http://en.wikipedia.org/wiki/Logical_disjunction, e per info Perl-specifico, vedere http://perldoc.perl.org/perlop.html#C-style-Logical-Or (per || e //) e http://perldoc.perl.org/perlop.html#Logical-or-and-Exclusive-Or (per or). Citazione più pertinente, dalla documentazione Perl su ||:

Binario "||" esegue un'operazione OR logico di cortocircuito. Cioè, se l'operando di sinistra è vero, l'operando di destra non viene neppure valutato. Il contesto scalare o di lista si propaga all'operando di destra se valutato.

Questo non lo spiega del tutto; nel caso in cui LHS valuti un valore di verità (vedi sotto per definizione), allora il valore di ritorno dell'operazione || è il valore dell'LHS, altrimenti è il valore dell'RHS.

In Perl, valori logici sono generalmente rappresentati da 0 (oa volte '' o undef) per falso e 1 per vero.Tuttavia, per essere più specifici, qualsiasi valore che non è uno dei tre valori falsi sopra è considerato vero, e talvolta i programmatori fanno riferimento a questa distinzione usando i termini informali "verità" e "falsa". IOW, 0, '' e undef sono falsi e tutto il resto è veritiero. Vedi http://www.perlmonks.org/?node=what%20is%20true%20and%20false%20in%20Perl%3F per ulteriori dettagli.

+0

Esiste una versione di questo che valuti prima il lato destro? Sto cercando una scorciatoia che significa '$ a = $ b se $ b'. – felwithe

+0

@felwithe Dipende da cosa vuoi che succeda a $ a nel caso in cui il condizionale RHS valuti la falsificazione. Se vuoi conservare il valore esistente di $ a, allora la tua istruzione di assegnazione funziona così com'è, dato che l'operatore infisso 'if' funziona come tu l'hai scritto, e impedirà l'assegnazione a tutti se è condizionale è falsa. Se vuoi un valore "predefinito" come "undef", allora penso che la risposta alla tua domanda sia tecnicamente no, ma puoi scrivere una subroutine per farlo: "sub if2 {return $ _ [1]? $ _ [0]: undef; } ', quindi chiamarlo:' $ a = if2 $ b, $ b; '. – bgoldst

+0

Ciao-- Intendo proprio come dice. Ho solo pensato che forse c'era una bella scorciatoia Perl di cui non sapevo nulla. – felwithe