|
||
| [IT] Kylix: un'idea per gestire gli errori | ||
|
Kylix: un'idea per gestire gli errori N.B.: Esistono tanti altri metodi, alcuni anche migliori. L'idea e' rivolta principalmente alle "console application". Dato un semplice programma, che non richieda particolari attenzioni sulla gestione degli errori, si vuole:
Rimane da definire nella sezione "const" una serie di costanti, come ad esempio:
Queste costanti saranno passate come parametri alle procedure "Error" e "FatalError". Come gia' detto, "FatalError" non e' altro che una estensione di Error, con l'unica differenza che arresta il programma. Supponendo di aver dichiarato "FreeResources" come procedura, possiamo quindi definire "FatalError" nel seguente modo: procedure FatalError(err: integer); begin Error(err); FreeResources(...); Halt; end;"Error" rappresenta il comportamento comune ai due tipi di errore, "FreeResources" libera le risorse occupate dall'applicazione, se necessario, e "Halt" termina l'esecuzione del programma. "Error" e' il cuore del sistema. Non dovra' far altro che analizzare il tipo di errore passato e stampare il messaggio opportuno. I testi dei messaggi da stampare possono essere memorizzati in liste di stringhe, in array di stringhe, su file, ecc. Il modo piu' semplice e' quello mostrato, cioe' la stampa diretta del messaggio di errore. Un esempio di definizione della procedura "Error" e' il seguente:
procedure Error(err: integer);
var _PROGRAM: String;
_VERSION: String;
_COPYRIGHT: String;
_EMAIL: String;
begin
_PROGRAM := 'test';
_VERSION := '1.0';
_COPYRIGHT := 'Pinco Pallino (c) 2001';
_EMAIL := 'pinco@pallino';
//In base al codice passato, stampo il messaggio opportuno
case err of
_ERR_USAGE: begin
Writeln(_PROGRAM+' '+_VERSION);
Writeln(_COPYRIGHT);
Writeln(_EMAIL);
Writeln;
Writeln('Uso:');
Writeln(' '+_PROGRAM+' [opzioni] -f <file> ...');
Writeln;
Writeln('Opzioni:');
Writeln(' --help: stampa questo testo di aiuto');
Writeln(' --verbose: fornisce dell''output aggiuntivo');
Writeln(' --force: ...');
end;
_ERR_FILE_REQUIRED: begin
Writeln('Manca il nome del file.');
end;
_ERR_MISSING_PARAMETERS: begin
Writeln('Mancano dei parametri.');
end;
_ERR_FILE_PROBLEMS: begin
Writeln('Problemi di gestione del file.');
end
else begin //sezione else del case
Writeln('Errore sconosciuto.');
end;
end; //end case
end;
Le stringhe "_PROGRAM", "_VERSION", "_COPYRIGHT", "_EMAIL", sono state dichiarate ed inizializzate
all'interno della procedura solamente per chiarirne il significato, non essenziale, comunque, ai
fini del funzionamento del sistema (e' solo un esempio).
Nei casi di errore non previsti, viene stampato un testo alternativo ("Errore sconosciuto")
definito nella sezione "else" dell'istruzione "case".
Possiamo utilizzare il sistema insieme alla gestione delle eccezioni con le istruzioni "try...except" e "try...finally". Per esempio, volendo catturare le eccezioni dovute ad operazioni su file, possiamo scrivere una cosa del tipo try <Istruzioni che "usano" un file> except on EInOutError do FatalError(_ERR_FILE_PROBLEMS); end;Se l'errore non lo si ritiene fatale, si puo' tranquillamente sostituire "Error" a "FatalError". "EImOutError e' l'eccezione sollevata in caso di problemi con le operazioni di I/O. Le procedure di errore non sono confinate alla gestione delle eccezioni. Possono essere utilizzate in qualsiasi momento ed in qualsiasi punto del programma. Ad esempio, se il numero di parametri passati al programma non e' corretto, possiamo usare "_ERR_USAGE" o "_ERR_ MISSING_PARAMETERS". if (ParamCount < 6) then begin FatalError(_ERR_USAGE); end;"ParamCount" e' una variabile gia' definita contenente il numero di parametri passati. Notare che in realta', il parametro "-f ciao.txt", per esempio, corrisponde a due parametri in Object Pascal, cioe' "-f" e "ciao.txt". La condizione mostrata stampa le modalita' di utilizzo del programma se il numero di parametri passato e' troppo basso. "Error" e "FatalError" sono modificabili ed ampliabili enormemente. Ad esempio, puo' essere inserito il supporto alla segnalazione del punto preciso del codice in cui si e' verificato l'errore. Un parere personale: avere una gestione piu' complicata e parametrizzata, e' indubbiamente una buona pratica di programmazione, specialmente nel contesto del riutilizzo del software. Pero', il tutto non e' sempre traducibile nelle esigenze della singola applicazione. Per comodita', segue un esempio parziale di implementazione del sistema descritto, comprendente tutte le funzioni.
program ...;
{$APPTYPE CONSOLE}
const
//Parametri del programma (non fanno parte del sistema, ma solo dell'esempio)
_PROGRAM = 'test';
_VERSION = '1.0';
_COPYRIGHT = 'Pinco Pallino (c) 2001';
_EMAIL = 'pinco@pallino';
//Codici di errore. Usare nomi e numeri a piacere.
_ERR_USAGE = 10;
_ERR_FILE_REQUIRED = 20;
_ERR_MISSING_PARAMETERS = 25;
_ERR_FILE_PROBLEMS = 40;
//Stampa l'errore indicato
procedure Error(err: integer);
begin
//In base al codice passato, stampo il messaggio opportuno
case err of
_ERR_USAGE: begin
Writeln(_PROGRAM+' '+_VERSION);
Writeln(_COPYRIGHT);
Writeln(_EMAIL);
Writeln;
Writeln('Uso:');
Writeln(' '+_PROGRAM+' [opzioni] -f <file> ...');
Writeln;
Writeln('Opzioni:');
Writeln(' --help: stampa questo testo di aiuto');
Writeln(' --verbose: fornisce dell''output aggiuntivo');
Writeln(' --force: ...');
end;
_ERR_FILE_REQUIRED: begin
Writeln('Manca il nome del file.');
end;
_ERR_MISSING_PARAMETERS: begin
Writeln('Mancano dei parametri.');
end;
_ERR_FILE_PROBLEMS: begin
Writeln('Problemi di gestione del file.');
end
else begin //sezione else del case
Writeln('Errore sconosciuto.');
end;
end; //end case
end;
//Stampa l'errore, libera le risorse ed esce dal programma
procedure FatalError(err: Integer);
begin
Error(err);
FreeResources(...);
Halt;
end;
//Libera le eventuali risorse occupate dal programma
procedure FreeResources(...);
begin
...
end;
//Sezione principale del programma
begin
...
end.
|
||
(c) 1999-2006
|