Perl è stato originariamente progettato come linguaggio di scripting per l'amministrazione di sistema, quindi il modello tradizionale di gestione degli errori era più procedurale. Tuttavia, nel tempo, nel linguaggio sono emerse tecniche avanzate per la gestione delle eccezioni e degli errori.
Nelle prime versioni di Perl, gli errori venivano catturati attraverso i valori di ritorno delle funzioni e il controllo della variabile globale $!, successivamente sono apparse strutture come eval (cattura dinamica), e moduli come Try::Tiny hanno aggiunto schemi di try-catch concisi e sicuri.
Il Perl standard non ha una sintassi try-catch integrata. Gli errori possono verificarsi sia nel codice Perl che nelle chiamate esterne (ad esempio, apertura di file). Se non si gestiscono esplicitamente gli errori, il programma può continuare a funzionare in uno stato imprevedibile. È necessario scegliere attentamente la tecnica di cattura degli errori a seconda del contesto, della complessità dell'applicazione e delle esigenze di affidabilità.
eval, racchiudendo il codice potenzialmente pericoloso in un blocco e analizzando il contenuto di $@ dopo l'esecuzionedie. Una generazione di errori più mirata e il rilancio di eccezioni già descritte avviene tramite il framework sinonEsempio di codice — gestione degli errori tramite Try::Tiny:
use Try::Tiny; try { open my $fh, '<', 'file.txt' or die "Impossibile aprire il file: $!"; while (<$fh>) { print $_; } } catch { warn "Si è verificato un errore: $_"; };
$@ e alle trappole di scopeIn quale caso il blocco eval non catturerà un errore di sistema?
Eval non cattura sempre l'errore se all'interno si verifica un'uscita fatale nelle librerie C (ad esempio, SEGFAULT da codice XS). Eval funziona solo con errori fatali di Perl, non con i crash delle estensioni C.
Cosa succede alla variabile $@ nei blocchi eval annidati?
Se all'interno di eval si chiama un altro eval, al suo uscita il valore di $@ verrà sovrascritto. Pertanto, dopo ogni eval è consigliabile salvare $@ in una variabile separata fino al successivo eval, per non perdere l'errore originale.
Perché i moduli di supporto come Try::Tiny dichiarano la variabile $@ localmente all'interno di catch/try?
Perché Perl ripulisce automaticamente $@ solo in caso di uscita positiva da try (eval). Un ritorno per errore, next, last può portare a lasciare $@ non pulito, e nel codice successivo ci sarà un errore "fantasma". I moduli come Try::Tiny creano una variabile scope-locale appositamente per questo.
Esempio:
try { die "Boom!"; } catch { print "Catturato: $_ "; # $_ - trappola dell'errore all'interno di catch };
Nel gestore di esportazione dei dati un errore di connessione al database viene catturato tramite eval, ma il valore di $@ non viene salvato, la registrazione non viene eseguita. Quando nel successivo eval si verifica un altro errore, il primo viene completamente perso.
Pro:
Contro:
Utilizzo di Try::Tiny per gestire sezioni critiche, tutti gli errori vengono registrati in un log separato, l'errore originale è salvato e correttamente visualizzato a schermo.
Pro:
Contro: