|
Argomento che si presenta molto di frequente è la necessità di effettuare una o più operazioni iterativamente, ovvero un certo numero di volte. Per questo scopo abbiamo diversi costrutti, il primo che andiamo ad affrontare si basa sulle keyword while e end ed ha la seguente sintassi: while condizione booleana codice end. in pratica fintanto che la condizione booleana è verificata viene eseguito il blocco di istruzioni fino alla fine segnata dal solito end. Ruby ammette la keyword do al termine della prima riga come opzionale. Crystal no, almeno in questa istruzione, altrove la ritroveremo.
L'output di questo programma è una sequenza di numeri da 0 a 4. Ovviamente la condizione iniziale in un qualche momento deve essere contraddetta, altrimenti si avrebbe un loop infinito. E' anche ovvio che sia possibile inserire quante istruzioni vogliamo tra il while e l'end. Se la condizione non è verificata all'inizio il ciclo viene saltato. Questa istruzione non presenta assolutamente difficoltà e le uniche problematiche possono riguardare la corretta fasatura della condizione booleana che regge il tutto. Potreste aver necessità di un ciclo che risulti simile ai do...while di altri linguaggi ovvero che garantisca almeno una volta l'esecuzione del codice interno al ciclo stesso. In Crystal, come in Ruby, non esiste tale sequenza ma può essere facilmente simulata ricorrendo a tre interessanti keyword che hanno anche altri usi: loop, do e break (oltre al solito end). La prima, loop, si occupa di generare un ciclo infinito se non interrotto. La seconda do, eccola qua, è necessaria per introdurre il blocco di istruzioni. La terza break, la userete se volete interrompere l'esecuzione. In questo senso break è utilizzabile anche all'interno di altri cicli, lo stesso while, ad esempio, che abbiamo visto in precedenza. Vediamo ora un esempio che unisce anche l'uso del controllo di flusso selettivo tramite il nostro if:
La sequenza dalla riga 4 alla 6 serve per interrompere l'esecuzione del ciclo. In questo caso l'esecuzione è garantita almeno per uno step, poi dipenderà dal raggiungimento della condizione di stop che avrete impostato. Se non la impostate o lo fate in modo errato ia sequenza di istruzioni si ripeterà all'infinito. Per inciso è facile impostare un ciclo infinito anche con il while while true istruzioni end e anche in questo caso il break vi potrà aiutare. se desiderate interrompere l'esecuzione dall'interno del programma. Altra istruzione abbastanza comoda è until. La sintassi è intuibile: until condizione istruzioni end
Quindi, nell'esempio, fino a che x non raggiunge un valore di 0 il programma stampa a video il valore corrente di x. Molto semplice, concettualmente molto vicino a while la differenza è ovviamente racchiusa nel fatto che while prosegue finchè la condizione indicata è vera, until prosegue finchè è falsa. Il ciclo for è quello forse storicamente più usato in quanto compare anche in molti ambiti di "attraversamento" di strutture dati sequenziali in molti linguaggi di programmazione. Ed è di facile uso e comprensione. Bene, Crystal NON supporta il for. La keyword è presente per essere utilizzata nelle macro ma non direttamente nel linguaggio. La cosa non è del tutto sorprendente, vedremo infatti che gli iteratori sono sufficienti per tutti gli scopi che ci prefiggeremo ed esistono altri meccanismi che possono perfettamente sostituirlo. Degli iteratori riparleremo a fondo intanto, come ulteriore esempio di ciclo, torniamo parlare degli interi e di alcuni metodi iterativi, iteratori veri e propri in realtà, ad essi applicabili anticipando quindi il discorso relativo agli iteratori stessi. Li ripetiamo (compare la keyword do): times, upto, downto. 5.times do puts "ciao" end questo stampa 5 volte a video la stringa "ciao" 1.upto(3) do puts "ciao" end questo stampa 3 volte a video la stringa "ciao" 5.downto(1) do puts "ciao" end anche questo stampa a video 5 volte la stringa "ciao" andando a ritroso. Penso che il codice sia autoesplicativo. Con le sequenze è possibile introdurre anche degli step, anche se il codice potrà apparire un po' poco chiaro a questo livello presento comunque un piccolo esempio: 0.step(to: 9, by: 2) do |i| puts "hi: #{i}" end Interessante è anche il discorso relativo a quelle istruzioni che possono modificare il normale flusso di un ciclo. Abbiamo già incontrato break che, come sappiamo può interrompere l'esecuzione della sequenza di istruzioni uscendo dal cliclo in cui si trova. Un'altra istruzione simile per logica è next che salta una iterazione.
presenta questo output:
perchè next alla riga 5 comporta che sui numeri pari, in base alla condizione espressa alla riga 4, venga eseguito un salto all'iterazione successiva. In altri linguaggi, ad esempio C# o Rust, l'istruzione analoga è continue. Anche questi cicli possono essere attribuiti ad una variabile ma il valore espresso sarà sempre un nil quindi di poco interesse. Come accennato, questo paragrafo va integrato con altre conoscenze relative ai range ed agli iteratori in generale. |