Ruby basics: blocchi di codice

Una delle particolarità di Ruby che lo rendono unico rispetto ad altri linguaggi di programmazione è costituita dai cosiddetti code blocks, vale a dire porzioni di codice che possono essere associati all’invocazione dei metodi.

Per fare un’analogia, i code blocks assomigliano in qualche modo alle funzioni anonime del linguaggio PHP o anche ai puntatori a funzione usati nel linguaggio C.

Come si definisce un code block

Un blocco di codice è costituito da una sequenza di istruzioni comprese tra { e }, oppure tra le parole chiave do e end.

In genere, la versione tra parentesi graffe è usata quando il blocco di codice è costituito da una singola istruzione, mentre l’altra notazione si usa quando si definiscono blocchi composti da più istruzioni.

Uso dei code blocks

Come anticipato, un blocco di codice è generalmente associato alla chiamata di un metodo, e ne rappresenta una sorta di parametro. Questo vuol dire che il particolare code block può essere invocato all’interno del metodo e ricevere a sua volta dei parametri (se previsti). Molto spesso i code blocks sono usati in corrispondenza di iteratori, come nel seguente esempio:

3.times { puts "Hello!" } # Stampa tre volte la stringa "Hello!"
4.times { |i| puts i } # Stampa le cifre da 0 a 3

Il secondo esempio mostra l’utilizzo di un parametro (i) che viene passato al blocco. Si tratta ovviamente di esempi elementari, quanto basta per rendere l’idea.

Un altro esempio, usando stavolta i delimitatori do e end, è il seguente:

%w{ tizio caio sempronio }.each do |name|
  l = name.length
  puts "Il nome #{name} è lungo #{l} caratteri"
end
Output della porzione di codice precedente

Invocare un code block da un metodo

Finora ho illustrato il passaggio di un code block a dei metodi predefiniti. Vediamo ora come è possibile definire un proprio metodo e invocare il blocco che gli viene passato.

Anche in questo caso ricorriamo ad un esempio molto elementare:

def call_me(first_name, last_name)
  first = first_name.capitalize
  last = last_name.capitalize
  yield(first, last)
end
call_me('MARCO', 'rossi') { |f, l| puts "Ciao, #{f} #{l}!"}
Output del precedente blocco chiamato sul metodo call_me

Nel caso mostrato, viene definito un semplice metodo che prende due parametri in ingresso (si suppone di tipo stringa), li converte in modo da avere la prima lettera maiuscola e poi invoca il blocco associato passandogli i due parametri così ottenuti. Il code block associato non fa altro che stampare i due valori all’interno di una stringa.

Dall’esempio si evince che, per invocare un code block passato ad un metodo, dal corpo del metodo si deve usare la parola chiave yield, passando eventuali parametri.

yield rappresenta quindi il riferimento al blocco di codice passato al metodo.


Gli esempi mostrati in questo articolo sono volutamente semplici; più avanti si vedranno casi in cui i blocchi di codice verranno utilizzati in situazioni via via più complesse.