Test e buchi
Scrivere test nel sorgente e usare ??? per completare il codice.
Un test verifica il codice nello stesso file. Con ??? puoi lasciare un’espressione incompleta e chiedere al compilatore quale tipo si aspetta. Entrambe le forme fanno parte del linguaggio.
test è una dichiarazione
test "the part that exists, works"
lunch = [Entry(name: "soup", calories: 120), Entry(name: "bread", calories: 250)]
assert total_calories(lunch) == 370
Un test ha una descrizione tra virgolette e un corpo indentato. Puoi scriverlo nello stesso file del codice da verificare. Le compilazioni ordinarie lo escludono dall’eseguibile; non servono librerie aggiuntive, cartelle separate o nomi di file particolari.
assert richiede un bool. Se il controllo fallisce, mostra l’espressione. Nei confronti mostra anche i due valori quando sono stampabili, per esempio numeri, stringhe o booleani:
$ heroes test points.hero
assert failed: dist2(a: Point(x: 0, y: 0), b: Point(x: 3, y: 4)) == 24
left: 25
right: 24
FAIL "the 3-4-5 triangle"
ok "a rectangle keeps its size when it moves"
2 tests, 1 failed
Gli altri test vengono eseguiti e mostrano i risultati. Il codice di uscita è diverso da zero, così uno script può rilevare il fallimento senza analizzare il testo dei messaggi.
??? è un’espressione legale
Scrivi ??? dove manca un valore. Il compilatore verifica il codice circostante e indica il tipo necessario per completare l’espressione.
# Written, tested, done.
function total_calories(entries: [Entry]) -> i64
total: i64 @= 0
for e in entries
total @ total + e.calories
return total
# Next up: the compiler will name the expected type and list `entries`,
# `total_calories` and the fields of `Entry` when it reaches this.
function heaviest(entries: [Entry]) -> Entry
???
# The hole can be one argument of an otherwise finished line.
function summary_of(entries: [Entry]) -> str
return "total " + total_calories(entries).to_str() + ", heaviest " + ???
Controlla quel file e il compilatore risponde:
$ heroes check holes.hero
hole at holes.hero:24:5
position: statement — any type, or none
this function returns: Entry
in scope:
entries: [Entry]
hole at holes.hero:28:74
expected type: str
in scope:
entries: [Entry]
functions that return it:
summary_of(entries: [Entry])
# The hole can be one argument of an otherwise finished line.
Nel secondo messaggio il compilatore indica che serve uno str. Elenca poi i nomi disponibili e le funzioni che restituiscono quel tipo, insieme alla prima riga dei rispettivi commenti. Queste informazioni aiutano a scegliere come completare il codice.
Tutto il resto viene controllato lo stesso
Un file con espressioni incomplete viene controllato per intero. Il controllo restituisce il codice 0 solo se non ci sono altri errori. Finché resta un ???, il compilatore non produce un eseguibile e indica il punto da completare:
$ heroes test holes.hero
no binary: 2 holes in holes.hero
hole at holes.hero:24:5
position: statement — any type, or none
this function returns: Entry
in scope:
entries: [Entry]
hole at holes.hero:28:74
expected type: str
in scope:
entries: [Entry]
functions that return it:
summary_of(entries: [Entry])
# The hole can be one argument of an otherwise finished line.
Il compilatore può quindi controllare un programma scritto a metà senza scambiarlo per uno finito. Un buco non può finire in un eseguibile.
Perché sta nel linguaggio e non dentro un editor
Una persona o un modello può ottenere queste informazioni direttamente dal compilatore, senza installare un editor o estensioni. I tre caratteri ??? indicano nel sorgente il punto ancora da completare.
function main()
print(summary_of([Entry(name: "tea", calories: 2)]))
Completa le due espressioni per poter eseguire main. Nel frattempo il compilatore può già controllare il resto del file.
Poi: Il confine con il C, da dove arriva tutto quello che il linguaggio non ha. Torna all’elenco dei capitoli. ← Prima: I moduli e i file
Esegui un programma tuo: bastano quattro comandi. Oppure prendi tutto il linguaggio in un file solo, e tutti i programmi già scritti.