Il problema
in questione
Quando
scrivete codice vi capita di mettere le cosiddette "print di debug" ? Penso
di sì, lo fanno tutti, specie se, come in java, il debugger è
qualcosa di poco usabile...
In
inglese si dice "instrumentating code" (se volete darvi un tono ;-), vuol
dire semplicemente intercalare il normale codice sorgente con delle istruzioni
di tipo "System.out.println(...)" (anche su stderr va bene) per
vedere i valori di certe variabili importanti nei momenti cruciali.
Però
poi il prodotto va distribuito... lo lasciate così? Inoltre, ancora
durante lo sviluppo, non è detto che vi interessino sempre e
tutte le "print" che avete messo...
Sarebbe
bello poter attivare e disattivare le "print" a seconda dei momenti
semplicemente cambiando una variabile e ricompilando il sorgente... e magari
si potrebbero anche attivare parzialmente, per categorie ad esempio.
Soluzione
proposta
In java
è possibile usare un analogo di "#IFDEF DEBUG" del C, è sufficiente
usare variabili "final static" e tutti gli "if" valutati su tali variabili
verranno in realtà valutati a compile time (es. un if su
una variabile booleana final static falsa NON verrà nemmeno tradotto
in bytecode!).
Se
si decidono un po' di categorie di debugging (es. NORMALE, PROFONDO, CICLI,
RETE, DB, etc.) è possibile categorizzare le "print" e attivarle
solo quando richiesto.
Basta
definire una variabile final static boolean per ogni categoria (io uso
sempre una classe astratta che chiamo Debug) e condizionare tutte le "print"
in base a queste variabili.
Per
abilitare e disabilitare le "print" basta editare il sorgente di Debug
e mettere a true o false le variabili opportune...
Esempio
Diciamo
di avere questa classe Debug:
public
abstract class Debug
{
/** eccezioni */
public final static boolean EXCEP = true;
public final static boolean DEEP_EX = true;
/** system.out... (generiche) */
public final static boolean PRINT = true;
public final static boolean DEEP = false;
/** system.out... (contatori dei loop) */
public final static boolean LOOP = false;
}
Nel
codice potremo quindi mettere statement del tipo:
if(Debug.PRINT)
System.out.println(p);
...
if(Debug.DEEP)
System.out.println(Integer.toString(current));
etc.
etc.
E piloteremo
così tutto il "debugging output" del nostro programma semplicemente
attivando o meno le variabili booleane (e ricompilando, mi raccomando!).
A
fine sviluppo (cioè mai ;-) potrete mettere a false tutto e il vostro
programma girerà silenzioso come un gatto addormentato...
Note
Chiaramente
questo è solo l'inizio, ognuno poi deve decidere quali sono le classi
di messaggi che gli interessano (nel mio esempio li catalogo sia per quantità
che per qualità) e quale sia il formato di uscita. Sarebbe infatti
bello definirsi un formato standard per questo tipo di output (un qualcosa
che contenga informazioni dettagliate sul contesto), ma questa è
un'altra storia... ;-)
|