Vai al contenuto
Leo

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:

Leo
# 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
fine

Dal programma principale lo porti dentro con importa, e da quel momento i suoi nomi sono disponibili come se li avessi scritti lì:

Leo
# principale.leo
importa "forme.leo"
scrivi "Area del cerchio: {area_cerchio(2)}"
scrivi "Area del rettangolo: {area_rettangolo(3, 4)}"
Risultato
Area del cerchio: 12.56636
Area del rettangolo: 12

importa "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:

Leo
importa forme come f
scrivi "Area del cerchio: {f.area_cerchio(2)}"
importa matematica come m
scrivi "Radice: {m.radice(9)}"
Risultato
Area del cerchio: 12.56636
Radice: 3.0

Con 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 a importa b che a sua volta importa a, 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 nome per 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

  1. 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.
  2. Crea un modulo conversioni.leo con funzioni come euro_in_dollari(euro) e km_in_miglia(km), poi usalo da un programma principale con importa conversioni come c.
  3. 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.