Parte III — Organizzare
Capitolo 12 — Dividere il programma in moduli
Un file solo va benissimo per i programmi piccoli. Ma quando un progetto cresce, tenere tutto in un unico file diventa come vivere in una stanza sola: si trova sempre peggio ogni cosa. La soluzione è dividere il codice in più file, ciascuno con un suo tema — le forme geometriche di qua, la gestione dei dati di là — e poi comporli. In Leo questo si fa con importa.
💡 L'idea — I cassetti della cucina
Dividere il codice in moduli è come organizzare una cucina in cassetti: le posate in uno, le spezie in un altro, gli strofinacci in un terzo. Non è che tu abbia più roba, ma sai sempre dove mettere le mani e non rovisti nel caos a ogni ricetta. Un modulo è esattamente questo: un cassetto con dentro le cose che stanno bene insieme.
Importare un file
Immagina di avere un file forme.leo con un po' di funzioni geometriche:
# forme.leo
costante PI_GRECO_MIO = 3.14159
funzione area_cerchio(raggio)
restituisci PI_GRECO_MIO * raggio * raggio
fine
funzione area_rettangolo(base, altezza)
restituisci base * altezza
fineDal programma principale lo porti dentro con importa, e da quel momento i suoi nomi sono disponibili come se li avessi scritti lì:
# principale.leo
importa "forme.leo"
scrivi "Area del cerchio: {area_cerchio(2)}"
scrivi "Area del rettangolo: {area_rettangolo(3, 4)}"Area del cerchio: 12.56636
Area del rettangolo: 12importa "forme.leo" esegue l'altro file e rende disponibili le sue funzioni e costanti. Leo cerca forme.leo prima nella cartella del file che importa, poi in quella del programma, poi in quella corrente — così i progetti restano portabili.
Importare «con il punto»
Portare tutti i nomi di un modulo nel proprio programma è comodo, ma se due moduli hanno una funzione con lo stesso nome nasce confusione. La forma importa ... come risolve: raccoglie i nomi del modulo sotto un'etichetta, e li usi con il punto. Funziona anche con i gruppi della libreria standard:
importa forme come f
scrivi "Area del cerchio: {f.area_cerchio(2)}"
importa matematica come m
scrivi "Radice: {m.radice(9)}"Area del cerchio: 12.56636
Radice: 3.0Con f.area_cerchio è chiarissimo da dove viene quella funzione. Questo stile è particolarmente prezioso nei progetti grandi, dove la provenienza di un nome aiuta a orientarsi.
Le regole del gioco
importa è semplice, ma ha qualche regola che vale la pena conoscere, perché ti protegge da errori sottili.
- Ogni file si esegue una volta sola, anche se lo importi da più punti. Non rischi di ripetere effetti collaterali o di rallentare il programma reimportando lo stesso codice.
- I giri circolari sono vietati. Se
aimportabche a sua volta importaa, Leo se ne accorge e si ferma subito con un messaggio che mostra il giro («Importazione circolare: a → b → a»). È un invito a ripensare la divisione: di solito la parte comune va estratta in un terzo file che entrambi importano. - Costanti e funzioni importate restano tali. Non puoi riassegnare una costante presa da un modulo; le funzioni restano funzioni. Le variabili del modulo, invece, si possono cambiare.
- Se un nome del modulo esiste già nel tuo programma, l'errore te lo dice e ti suggerisce la forma
importa "..." come nomeper tenerli separati.
🦁 Curiosità — Non ripeterti (DRY)
Uno dei principi più citati di tutta la programmazione si riassume in tre lettere: DRY, «Don't Repeat Yourself», cioè «non ripeterti». L'espressione fu resa celebre dal libro The Pragmatic Programmer (1999) di Andrew Hunt e David Thomas. L'idea è semplice: una cosa va scritta in un posto solo e poi riusata, così quando cambia la correggi una volta e non dieci. I moduli servono proprio a questo.
Oltre: la libreria Python, per chi vuole
Leo include già quasi tutto ciò che serve per l'uso normale — lo scopriremo nel tour del Capitolo 15. Ma per chi, un giorno, avesse bisogno di un pacchetto dell'immenso ecosistema Python, la porta c'è: importa python "nome". È una funzionalità da esperti, e non ne avrai bisogno per un bel pezzo; la citiamo solo perché tu sappia che il tetto, sopra la tua testa, è molto alto. Quando quel momento verrà, la Guida al linguaggio e la scheda PACCHETTI.md ti accompagneranno.
Prova tu
- Dividi uno dei programmi dei capitoli scorsi in due file: un modulo con le funzioni e un file principale che le importa e le usa.
- Crea un modulo
conversioni.leocon funzioni comeeuro_in_dollari(euro)ekm_in_miglia(km), poi usalo da un programma principale conimporta conversioni come c. - Prova di proposito a creare un'importazione circolare tra due file e leggi il messaggio d'errore. Poi sistemala estraendo la parte comune in un terzo file.