2013-05-23 14 views
5
eval { 
    # here is put some code that may throw exception 
    return 1; 
} or do { 
    my $error = [email protected]; 
    # Handle error. 
}; 
  1. Ha il seguente stile proteggere contro $ @ non essere impostato correttamente?
  2. Cosa significa "1;" proteggere contro?
  3. Il "o do {" è migliore del proverbio "if ($ @) {"? Se è così, perché?
+6

Il modo più semplice per la gestione degli errori a prova di proiettile con un eval blocco è quello di utilizzare un modulo che implementa try-catch, come la sintassi, per esempio [Prova :: Piccolo] (https://metacpan.org/module/DOY/Try-Tiny-0.12/lib/Try/Tiny.pm). La documentazione elenca ulteriori avvertimenti a cui potresti essere interessato. – amon

+1

Questo è chiaramente il risultato di qualcuno che applica la [raccomandazione di Perl :: Critico] (http://p3rl.org/Perl::Critic::Policy::ErrorHandling :: RequireCheckingReturnValueOfEval). – daxim

+0

@daxim Che generalmente non è una cosa negativa :) – nslntmnx

risposta

9

Vedere la documentazione Try::Tiny per la discussione delle cose che possono andare male quando si utilizza eval come una dichiarazione try tipo, come possono essere evitati, e perché il codice scritto si conclude con 1 (per garantire il blocco eval restituisce un vero valore se completa con successo).

Dopo averlo letto, prendere in considerazione l'utilizzo di Try :: Tiny invece di passare attraverso tutte le rotazioni per assicurarsi che ciascuno dei tuoi eval funzioni correttamente come try. La pigrizia è il first great virtue di un programmatore, dopo tutto.

+0

Mentre questa risposta propone un approccio alternativo, piuttosto che rispondere direttamente alla domanda, penso che sia la risposta più "pratica", quindi lo accetto. – nslntmnx

1

Si potrebbe scrivere sopra eval come,

my $result = eval { 
    # here is put some code that may throw exception 
    1; # Why is the "1;" here ? 
}; 

In questo caso $result sarà 1 solo se non c'era un'eccezione all'interno eval, ed al contrario undef.

Quindi in questo caso particolare, assicura che or do {..} non venga eseguito se non ci sono state eccezioni.

if ([email protected]) {..} è forse un modo più idiomatico di fare la stessa cosa, e [email protected] è sempre impostato quando eval{..} fallisce.

+1

-1, ho downvotato questo perché l'ultima frase è meno valida rispetto al consiglio in [P: C: P: ErrorHandling :: RequireCheckingReturnValueOfEval] (http://p3rl.org)/Perl :: Critic :: Policy :: :: ErrorHandling RequireCheckingReturnValueOfEval). Rompere l'intera espressione in più istruzioni induce bug sui vecchi Perls ( daxim

+0

Il codice sopra non è una proposta ma una spiegazione alla domanda OP. –

+0

Ancora non una scusa per mostrare codice buggato e non menzionare le circostanze. – daxim

1

Cosa cambia, se del caso, sono tenuti a fare la seguente Perl prova di proiettile eval?

se ricordo bene, se vi preoccupate per il contenuto di $ @ (e non solo se sia vero o no) è inoltre necessario fare attenzione a $ @ sovrascrittura da altro codice che muore prima di guardare (vedi risposta alla 1. sotto).

  1. Ha il seguente stile proteggere contro $ @ non essere impostato correttamente?

Sì, $ @ può essere sovrascritto nel tempo tra la eval e if. Il caso più comune per questo, se non ricordo male, è il metodo DELETE di un oggetto che sta andando fuori ambito (perché era nell'eval) usando un successo eval.

Cosa significa "1;" proteggere contro?

Il valore vero costante (non deve essere 1) è lì per garantire che il blocco eval restituisca un valore vero. Se il codice nel blocco muore, il blocco restituisce una stringa vuota e viene eseguito il blocco do.Se sei certo che l'ultima affermazione nel blocco sarà sempre vera, allora non è necessaria; tuttavia, non vi è alcun motivo per non essere solo sicuri del valore costante.

Il "o do {" è migliore del proverbio "if ($ @) {"? Se è così, perché?

Evita di dover memorizzare il valore di ritorno del blocco eval. Si potrebbe dire

my $result = eval { 
    #do stuff 
    1; 
}; 
unless ($result) { 
    # handle error 
} 
+0

Grazie per la tua risposta dettagliata. Prima di accettare questa risposta, sono preoccupato per l'ultimo blocco di codice. L'ultimo blocco di codice ha più probabilità di soffrire di $ @ uscendo dall'ambito di "o do {". Il mio ragionamento è che un distruttore può essere chiamato tra le due linee di codice nell'esempio. Forse ho sbagliato? Forse una leggera modifica a "o fai {" o un commento in alto per evitare a causa della perdita di scopo di $ @? Non sto cercando di essere schizzinoso, ma sto cercando di rendere chiaro per le persone che taglieranno e supereranno questo codice. Ancora una volta, grazie per la tua risposta dettagliata. – nslntmnx

Problemi correlati