Perl - Gestione degli errori

L'esecuzione e gli errori vanno sempre insieme. Se stai aprendo un file che non esiste. quindi se non hai gestito correttamente questa situazione, il tuo programma è considerato di scarsa qualità.

Il programma si interrompe se si verifica un errore. Quindi una corretta gestione degli errori viene utilizzata per gestire vari tipi di errori, che possono verificarsi durante l'esecuzione di un programma e intraprendere l'azione appropriata invece di interrompere completamente il programma.

È possibile identificare e intercettare un errore in molti modi diversi. È molto facile intercettare gli errori in Perl e quindi gestirli correttamente. Ecco alcuni metodi che possono essere utilizzati.

L'istruzione if

Il if statementè la scelta più ovvia quando è necessario controllare il valore restituito da un'istruzione; per esempio -

if(open(DATA, $file)) {
   ...
} else {
   die "Error: Couldn't open the file - $!";
}

Qui la variabile $! restituisce il messaggio di errore effettivo. In alternativa, possiamo ridurre l'affermazione a una riga nelle situazioni in cui ha senso farlo; per esempio -

open(DATA, $file) || die "Error: Couldn't open the file $!";

La funzioneless

Il unlessla funzione è l'opposto logico di if: le istruzioni possono ignorare completamente lo stato di successo ed essere eseguite solo se l'espressione restituisce false. Ad esempio:

unless(chdir("/etc")) {
   die "Error: Can't change directory - $!";
}

Il unlessè meglio utilizzare quando si desidera sollevare un errore o un'alternativa solo se l'espressione fallisce. L'affermazione ha senso anche se usata in un'istruzione di una sola riga:

die "Error: Can't change directory!: $!" unless(chdir("/etc"));

Qui moriamo solo se l'operazione chdir fallisce e si legge bene.

L'operatore ternario

Per test molto brevi, puoi usare l'operatore condizionale ?:

print(exists($hash{value}) ? 'There' : 'Missing',"\n");

Non è così chiaro qui cosa stiamo cercando di ottenere, ma l'effetto è lo stesso dell'uso di un file if o unlessdichiarazione. L'operatore condizionale viene utilizzato al meglio quando si desidera restituire rapidamente uno dei due valori all'interno di un'espressione o un'istruzione.

La funzione warn

La funzione warn genera solo un avviso, un messaggio viene stampato su STDERR, ma non viene intrapresa alcuna azione. Quindi è più utile se vuoi solo stampare un avviso per l'utente e procedere con il resto dell'operazione -

chdir('/etc') or warn "Can't change directory";

La funzione die

La funzione die funziona proprio come warn, tranne per il fatto che chiama anche exit. All'interno di uno script normale, questa funzione ha l'effetto di terminare immediatamente l'esecuzione. Dovresti usare questa funzione nel caso in cui sia inutile procedere se c'è un errore nel programma -

chdir('/etc') or die "Can't change directory";

Errori all'interno dei moduli

Ci sono due diverse situazioni che dovremmo essere in grado di gestire:

  • Segnalare un errore in un modulo che cita il nome del file e il numero di riga del modulo: è utile quando si esegue il debug di un modulo o quando si desidera specificamente sollevare un errore relativo al modulo, piuttosto che relativo allo script.

  • Segnalazione di un errore all'interno di un modulo che cita le informazioni del chiamante in modo da poter eseguire il debug della riga all'interno dello script che ha causato l'errore. Gli errori generati in questo modo sono utili all'utente finale, perché evidenziano l'errore in relazione alla riga di origine dello script chiamante.

Il warn e diele funzioni funzionano in modo leggermente diverso da quello che ti aspetteresti quando chiamate dall'interno di un modulo. Ad esempio, il modulo semplice -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   warn "Error in module!";
}
1;

Quando viene chiamato da uno script come di seguito -

use T;
function();

Produrrà il seguente risultato:

Error in module! at T.pm line 9.

Questo è più o meno quello che potresti aspettarti, ma non necessariamente quello che vuoi. Dal punto di vista di un programmatore di moduli, le informazioni sono utili perché aiutano a indicare un bug all'interno del modulo stesso. Per un utente finale, le informazioni fornite sono abbastanza inutili e per tutti tranne che per i programmatori incalliti, sono completamente inutili.

La soluzione a questi problemi è il modulo Carp, che fornisce un metodo semplificato per segnalare errori all'interno dei moduli che restituiscono informazioni sullo script chiamante. Il modulo Carp fornisce quattro funzioni: carpa, cluck, gracidare e confessare. Queste funzioni sono discusse di seguito.

La funzione carpa

La funzione carp è l'equivalente di base di warn e stampa il messaggio su STDERR senza effettivamente uscire dallo script e stampare il nome dello script.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   carp "Error in module!";
}
1;

Quando viene chiamato da uno script come di seguito -

use T;
function();

Produrrà il seguente risultato:

Error in module! at test.pl line 4

La funzione cluck

La funzione cluck è una sorta di carpa sovralimentata, segue lo stesso principio di base ma stampa anche una traccia dello stack di tutti i moduli che hanno portato alla chiamata della funzione, comprese le informazioni sullo script originale.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp qw(cluck);

sub function {
   cluck "Error in module!";
}
1;

Quando viene chiamato da uno script come di seguito -

use T;
function();

Produrrà il seguente risultato:

Error in module! at T.pm line 9
   T::function() called at test.pl line 4

La funzione gracchiare

Il croak funzione è equivalente a die, tranne per il fatto che segnala il chiamante di un livello superiore. Come die, anche questa funzione esce dallo script dopo aver segnalato l'errore a STDERR -

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   croak "Error in module!";
}
1;

Quando viene chiamato da uno script come di seguito -

use T;
function();

Produrrà il seguente risultato:

Error in module! at test.pl line 4

Come per le carpe, si applicano le stesse regole di base per quanto riguarda l'inclusione delle informazioni sulla linea e sul file in base alle funzioni di avvertimento e di matrice.

La funzione confessare

Il confess la funzione è simile cluck; chiama die e quindi stampa una traccia dello stack fino allo script di origine.

package T;

require Exporter;
@ISA = qw/Exporter/;
@EXPORT = qw/function/;
use Carp;

sub function {
   confess "Error in module!";
}
1;

Quando viene chiamato da uno script come di seguito -

use T;
function();

Produrrà il seguente risultato:

Error in module! at T.pm line 9
   T::function() called at test.pl line 4