Usare un debugger
§ Un debugger
è un programma che potete usare per
eseguire un altro
programma e analizzare il suo comportamento durante l’esecuzione.
§ Potete interrompere e far proseguire il vostro programma,
vedere il contenuto
delle variabili quando arrestate temporaneamente l’esecuzione,
scegliere
quanti passi di programma eseguire prima dell’interruzione
successiva.
§ Più grandi sono i vostri programmi, più difficile sarà
correggerli inserendo
semplicemente enunciati di stampa.
§ I debugger
possono far parte di ambienti di
sviluppo integrato (es. BlueJ,
Eclipse) o essere programmi a se stanti (es.
Jswat).
§ Tre concetti chiave:
§ punti di arresto (breakpoints)
§ esecuzione del programma una riga alla volta
(single-stepping)
§ ispezione del valore di singole
variabili (inspecting variables)
Il debugger fermo a un punto di arresto
Il debugger fermo a un
punto di arresto
Ispezionare variabili
Ispezionare variabili
Debugging
§ L’esecuzione viene sospesa al raggiungimento del
breakpoint
§ Quando fate partire il debugger, il programma viene
eseguito a piena
velocità fino al raggiungimento di un punto di arresto
§ Quando il programma si è fermato è possibile:
§ Ispezionare le variabili
§ Eseguire il programma una riga alla volta
§ Oppure continuare l’esecuzione del programma a velocità
piena fino al
raggiungimento del breakpoint successivo
§ Quando il programma termina, termina anche l’esecuzione
del debugger
§ I punti di arresto rimangono attivi finché non vengono
esplicitamente
rimossi
§ Due tipi di comando single-step:
§ step into (fai un passo all’interno)
§ step over (fai un passo scavalcando)
Attività di debugging
§ Riprodurre l'errore
§ Semplificare l'errore
§ Divide and conquer / Top-down
§ Sapere cosa dovrebbe fare il programma / metodo
§ Controllare tutti i dettagli
§ Capire bene l'errore prima di
correggerlo
Esempio di single step
Linea attuale:
String input = in.next();
Word w = new Word(input);
int
syllables = w.countSyllables();
System.out.println("Syllables
in " + input + ": " +
syllables);
Quando eseguite un comando di tipo step over,
procedete fino alla riga
successiva:
String input = in.next();
Word w = new Word(input);
int syllables =
w.countSyllables();
System.out.println("Syllables
in " + input + ": " +
syllables);
Esempio di single step
Tuttavia se eseguite un comando di tipo step into vi
trovate nella prima
linea del metodo countSyllables:
public int countSyllables()
{
int
count = 0;
int end = text.length() -
1;
. . .
}
Un esempio di sessione di debugging
§ La classe word ha il compito di contare le sillabe in una
parola
§ Ogni gruppo di vocali adiacenti (a, e, i, o, u, y) fa
parte di una sillaba
§ Tuttavia, una “e” alla fine di una parola non forma una
sillaba
§ Ogni parola ha almeno una sillaba anche se le regole
precedenti
forniscono un conteggio nullo
§ Eventuali caratteri all’inizio o alla fine della stringa
che non siano
lettere
vengono eliminati.
File Word.java
01: /**
02: Classe che descrive una parola in un documento.
03: */
04: public class Word
05: {
06: /**
07: Costruisce una parola eliminando caratteri iniziali e
08: finali che non siano lettere, come i segni di punteggiatura.
09: @param s la stringa da analizzare
10: */
11: public Word(String
s)
12: {
13: int i = 0;
14: while (i <
s.length() && !Character.isLetter(s.charAt(i)))
15: i++;
16: int j = s.length()
- 1;
17: while (j > i
&& !Character.isLetter(s.charAt(j)))
18: j--;
19: text =
s.substring(i, j);
20: }
21:
22: /**
23: Restituisce il testo della parola dopo aver rimosso
24: caratteri iniziali e finali che non siano lettere.
25: @return il testo della parola
26: */
27: public String
getText()
28: {
29: return text;
30: }
31:
32: /**
33: Conta le sillabe presenti nella parola.
34: @return il numero di sillabe
35: */
36: public int
countSyllables()
37: {
38: int count = 0;
39: int end =
text.length() - 1;
40: if (end < 0)
return 0; // La stringa vuota non ha sillabe
41:
42: // Una e alla fine della parola non conta come vocale
43: char ch =
Character.toLowerCase(text.charAt(end));
44: if (ch == 'e')
end--;
46: boolean
insideVowelGroup = false;
47: for (int i = 0; i
<= end; i++)
48: {
49: ch =
Character.toLowerCase(text.charAt(i));
50: String vowels =
"aeiouy";
51: if
(vowels.indexOf(ch) >= 0)
52: {
53: // ch è una vocale
54: if (!insideVowelGroup)
55: {
56: // inizia un nuovo gruppo di vocali
57: count++;
58: insideVowelGroup = true;
59: }
60: }
61: }
62:
63: // Ogni parola ha almeno una sillaba
64: if (count == 0)
65: count = 1;
66:
67: return count;
68: }
69:
70: private String text;
71:
}
File SyllableCounter.java
01: import java.util.Scanner;
02:
03: /**
04: Questo programma conta le sillabe di tutte le parole di una
frase.
05: */
06: public class
SyllableCounter
07: {
08: public static void
main(String[] args)
09: {
10: Scanner in = new
Scanner(System.in);
11:
12: System.out.println("Enter
a sentence ending in a period.");
13:
14: String input;
15: do
16: {
17: input = in.next();
18: Word w = new
Word(input);
19: int syllables =
w.countSyllables();
20: System.out.println("Syllables
in " + input + ": "
21: + syllables);
22:
}
23: while (!input.endsWith("."));
24: }
25:
}
Il programma di debug
§ Fornendo questi dati in ingresso: "hello yellow peach. " viene
visualizzato quanto segue (che non è molto promettente):
Syllables in hello: 1
Syllables in yellow: 1
Syllables in peach.: 1
§ Impostare un punto di arresto nella prima linea del metodo
del
countSyllables della classe word
§ Fate partire il programma che chiederà i dati in ingresso,
ricevuti i quali
si arresterà al breakpoint impostato
§ Il metodo controlla l’ultimo carattere della parola per
vedere se è una
“e”
Il programma di debug
Collaudare il metodo
countSyllables con il debugger
§ Vediamo se questo funziona correttamente: eseguite il
programma fino
alla linea in cui viene fatto il controllo. Ora ispezionate la
variabile ch.
§ Potete verificare che ch contiene il valore “l”
Collaudare il costruttore di word con il
debugger
§ Fornire di nuovo i dati in ingresso
§ Impostare un breakpoint dopo la fine del secondo ciclo
§ Ispezionare i valori i e j
§ i vale 0 e j vale 4. Ciò ha
senso perché non ci sono segni di
punteggiatura da ignorare
§ Perché text
viene impostato a “hell”?
§ Tipico errore “per scarto di uno”: il metodo substring considera
le
posizioni fino al secondo parametro senza includerlo
text = substring(i, j);
dovrebbe essere:
text = s.substring(i, j + 1);
Collaudare il costruttore di word con il
Debugger
Collaudare il costruttore
di Word con il debugger
Un altro errore
§ Correggete questo errore
§ Compilate nuovamente il programma
§ Provate di nuovo i tre casi di prova
Syllables in hello: 1
Syllables in yellow: 1
Syllables in peach.: 1
§ C’è ancora un problema
§ Eliminate tutti i punti di arresto e impostate un nuovo
breakpoint
nel metodo countSyllables
§ Fornite in ingresso la stringa “hello”
Collaudare di nuovo con il debugger
countSyllables
§ Iniziate a eseguire il programma passo dopo passo, in
modalità single
step, all’interno del metodo
boolean insideVowelGroup =
false;
for (int i = 0; i <=
end; i++)
{
ch = Character.toLowerCase(text.charAt(i));
if
("aeiouy".indexOf(ch) >= 0)
{
// ch è una vocale
if (!insideVowelGroup)
{
// Inizia un nuovo gruppo di vocali
count++;
insideVowelGroup = true;
}
}
}
Collaudare di nuovo con il debugger
countSyllables
§ Nella prima iterazione del ciclo, il debugger non esegue
l’enunciato if.
Ciò è corretto perché la prima lettera “h” non
è una vocale.
§ Nella seconda iterazione il debugger entra nell’enunciato if come
dovrebbe perché la seconda lettera “e” è una vocale. La variabile count
viene incrementata.
§ Nella terza iterazione l’enunciato if viene ignorato
nuovamente perché
la lettera “l” non è una vocale.
§ Nella quinta interazione succede qualcosa di strano: la
lettera “o” è una
vocale e l’enunciato if viene eseguito, ma il secondo
enunciato if viene
ignorato e la
variabile count
non viene nuovamente incrementata.
Correggere l’errore
§ La lettura di una consonante dovrebbe riportare insideVowelGroup al
valore false
§ Per correggerlo:
if ("aeiouy".indexOf(ch) >= 0)
{
. . .
}
else insideVowelGroup = false;
§ Ora compilate nuovamente ed eseguite di nuovo il collaudo,
ottenendo:
Syllables in hello: 2
Syllables in yellow: 2
Syllables in peach.: 1
§ Il debugger è ora privo di errori? Questa non è una
domanda alla quale il
debugger possa
rispondere.
Nessun commento:
Posta un commento