8.  Scrivere Nuovi Metodi

 

Come abbiamo visto, i loop e gli iteratori ci permettono di fare e rifare la stessa cosa (eseguire lo stesso codice ciclicamente). Tuttavia, alle volte vogliamo fare la stessa cosa un certo numero di volte, ma in parti differenti del programma. Per esempio, immaginiamo di dover scrivere un quiestionario per uno studente di psicologia. Sulla base degli studenti di psicologia che conosco e dei quiestionari che mi hanno proposto, posso dire che probabilmente si tratterebbe di qualcosa di questo tipo:

# encoding: utf-8
puts 'Ciao, e grazie per il tuo tempo dedicato'
puts 'ad aiutarmi con questo esperimento. Il mio esperimento'
puts 'riguarda il modo in cui le persone si sentono rispetto al'
puts 'cibo messicano. Pensa solo al cibo messicano'
puts 'e cerca di rispondere ad ogni domanda onestamente,'
puts 'con un "si" oppure un "no". Il mio esperimento'
puts 'non ha nulla a che vedere con la pipì a letto.'
puts

#  Chiediamo queste domande, ma ignoriamo le risposte.

rispValida = false
while (not rispValida)
  puts 'Ti piacciono i tacos?'
  risposta = gets.chomp.downcase
  if (risposta == 'si' or risposta == 'no')
    rispValida = true
  else
    puts 'Per favore rispondi "si" o "no".'
  end
end

rispValida = false
while (not rispValida)
  puts 'Ti piace il burrito?'
  risposta = gets.chomp.downcase
  if (risposta == 'si' or risposta == 'no')
    rispValida = true
  else
    puts 'Per favore rispondi "si" or "no".'
  end
end

#  Prestiamo atdiecizione a *questa* risposta, comunque.
rispValida = false
while (not rispValida)
  puts 'Bagni il letto?'
  risposta = gets.chomp.downcase
  if (risposta == 'si' or risposta == 'no')
    rispValida = true
    if risposta == 'si'
      bagnaLetto = true
    else
      bagnaLetto = false
    end
  else
    puts 'Per favore rispondi "si" o "no".'
  end
end

rispValida = false
while (not rispValida)
  puts 'Ti piacciono i chimichanga?'
  risposta = gets.chomp.downcase
  if (risposta == 'si' or risposta == 'no')
    rispValida = true
  else
    puts 'Per favore rispondi "si" o "no".'
  end
end

puts 'Giusto qualche altra domanda, abbiamo quasi finito...'

rispValida = false
while (not rispValida)
  puts 'Ti piacciono le sopapillas?'
  risposta = gets.chomp.downcase
  if (risposta == 'si' or risposta == 'no')
    rispValida = true
  else
    puts 'Per favore rispondi "si" o "no".'
  end
end

#  Chiedi tante domande sul cibo messicano.

puts
puts 'RESOCONTO:'
puts 'Grazie per aver dedicato del tempo a questo'
puts 'esperimento.  In effetti, questo esperimento'
puts 'non c'entrava nulla col cibo messicano. In realtà '
puts 'serviva a capire se fai la pipì a letto. Il cibo messicano'
puts 'era lì solo per distrarti e farti abbassare la guardia'
puts 'nella speranza che così avresti risposto più onestamente.'
puts 'Grazie ancora.'
puts
puts bagnaLetto
Ciao, e grazie per il tuo tempo dedicato
ad aiutarmi con questo esperimento. Il mio esperimento
riguarda il modo in cui le persone si sentono rispetto al
cibo messicano. Pensa solo al cibo messicano
e cerca di rispondere ad ogni domanda onestamente,
con un "si" oppure un "no". Il mio esperimento
non ha nulla a che vedere con la pipì a letto.

Ti piacciono i tacos?
si
Ti piace il burrito?
si
Bagni il letto?
Cosa!?
Per favore rispondi "si" o "no".
Bagni il letto?
NO
Ti piacciono i chimichangas?
si
Giusto qualche altra domanda, abbiamo quasi finito...
Ti piacciono le sopapillas?
si

RESOCONTO:
Grazie per aver dedicato del tempo a questo
esperimento.  In effetti, questo esperimento
non c'entrava nulla col cibo messicano. In realtà
serviva a capire se fai la pipì a letto. Il cibo messicano
era lì solo per distrarti e farti abbassare la guardia
nella speranza che così avresti risposto più onestamente.
Grazie ancora.

false

(NdC: Nota che la risposta 'NO' è accettata anche se è in maiuscolo perché il testo inserito dall'utente viene convertito in lettere minuscole dal metodo .downcase chiamato dopo gets.chomp. Se vuoi mettere più pressione all'intervistato puoi provare a toglierlo in modo da considerare valide solo risposte scritte, con calma, in minuscolo).

Era un programma piuttosto lungo, con parecchia ripetizione. (Tutte le porzioni di codice attorno alle domande sul cibo messicano erano identiche, e la domanda sul bagnare il letto era solo leggermente differente). La ripetizione è una brutta cosa. Eppure, non possiamo inserirla in un grande loop o iteratore, perché certe volte ci sono delle cose che vogliamo fare fra le domande. In situazioni come queste, è meglio scrivere un metodo. Ecco come:

# encoding: utf-8
def muggito
  puts 'muuuuuuu...'
end

 

Uh... il nostro programma non ha muggito. E perché no? Perché non gli abbiamo detto di farlo. Gli abbiamo detto come si fa un muggito, ma non gli abbiamo mai detto effettivamente di farlo. Proviamoci ancora:

# encoding: utf-8
def muggito
  puts 'muuuuuuu...'
end

muggito
muggito
puts 'coin-coin'
muggito
muggito
muuuuuuu...
muuuuuuu...
coin-coin
muuuuuuu...
muuuuuuu...

Ahhh, molto meglio. (In caso tu non conosca il francese, quella era un'anatra francese nel mezzo del programma. In Francia, le anatre fanno "coin-coin").

Quindi abbiamo definito il metodo muggito. (I nomi dei metodi, come i nomi delle variabili, cominciano con una lettera minuscola. Ci sono alcune eccezioni, comunque, come + e ==). Ma i metodi non devono sempre essere associati agli oggetti? Ebbene sì, e in questo caso (così come con puts e gets), il metodo è semplicemente associato con l'oggetto che rappresenta l'intero programma. Nel prossimo capitolo vedremo come aggiungere metodi ad altri oggetti. Ma prima...

I Parametri dei Metodi

Potresti aver notato che alcuni metodi (come gets, to_s, reverse...) li puoi semplicemente chiamare su un oggetto. Tuttavia, altri metodi (come +, -, puts...) hanno bisogno di parametri per dire all'oggetto come eseguire il metodo. Per esempio, non diresti mai solo 5+, vero? Stai dicendo a 5 di sommare, ma non gli stai dicendo cosa sommmare.

Per aggiungere un parametro a muggito (diciamo, il numero di muggiti), si fa così:

# encoding: utf-8
def muggito numeroDiMuggiti
  puts 'muuuuuuu...'*numeroDiMuggiti
end

muggito 3
puts 'oink-oink' #  Questo è un maiale inglese, NdC.
muggito  #  Questo dovrebbe dare errore perché manca il parametro.
muuuuuuu...muuuuuuu...muuuuuuu...
oink-oink
#<ArgumentError: wrong numero of arguments (0 for 1)>

numeroDiMuggiti è una variabile che punta al parametro passato. Lo ripeto, perché sia chiaro: numeroDiMuggiti è una variabile che punta al parametro passato. Quindi se scrivo muggito 3, allora il parametro è 3, e la variabile numeroDiMuggiti punta a 3.

Come puoi dedurre dall'errore (NdC: che si traduce come "ErroreDiArgomento: numero sbagliato di argomenti (0 per 1)"), il parametro è ora richiesto. Dopotutto, muggito per cosa deve moltiplicare 'muuuuuuu...' se non gli passi un parametro? Il tuo povero computer non ne ha idea.

Se gli oggetti in Ruby sono come i sostantivi in Italiano, e i metodi sono come i verbi, allora puoi pensare ai parametri come agli avverbi (come con muggito, dove il parametro ci dice come fare il muggito) o certe volte come a dei complemento oggetto (come con puts, sove il paramentro è cosa viene putsato).

Le Variabili Locali

Nel seguente programma, ci sono due variabili:

# encoding: utf-8
def raddoppiaQuesto num
  numPer2 = num*2
  puts num.to_s+' raddoppiato è '+numPer2.to_s
end

raddoppiaQuesto 44
44 raddoppiato è 88

Le variabili sono num and numPer2. Ed entrambe si trovano all'interno del metodo raddoppiaQuesto. Queste (e tutte le variabili che abbiamo visto finora) sono variabili locali. Questo significa che vivono all'interno del metodo, e non possono uscirne. Se ci provi, otterrai un errore:

# encoding: utf-8
def raddoppiaQuesto num
  numPer2 = num*2
  puts num.to_s+' raddoppiato è '+numPer2.to_s
end

raddoppiaQuesto 44
puts numPer2.to_s
44 raddoppiato è 88
#<NameError: undefined local variable or method `numPer2' for #<StringIO:0x82ba21c>>

Undefined local variable... [ NdC: "ErroreDiNome: variabile locale o metodo 'numPer2' non definito per ..." ] In realtà abbiamo quella variabile locale, ma non era locale nel punto in cui abbiamo cercato di utilizzarla; è locale solo rispetto al metodo.

Questo potrebbe sembrare sconveniente, ma in realtà è cosa buona e giusta. Seppur significa che non si ha accesso alle variabili all'interno dei metodi, implica anche che le tue variabili non possono essere accedute da altri metodi, che quindi non le possono rovinare:

# encoding: utf-8
def piccolaPeste var
  var = nil
  puts 'HAHA!  Ho rovinato la tua variabile!'
end

var = 'Non puoi nemmeno toccare la mia variabile!'
piccolaPeste var
puts var
HAHA!  Ho rovinato la tua variabile!
Non puoi nemmeno toccare la mia variabile!

In realtà ci sono due variabili in quel piccolo programma che si chiamano var: una all'interno di piccolaPeste e una al suo esterno. Quando abbiamo chiamato piccolaPeste var, in realtà abbiamo solo passato la stringa da una var all'altra, così che entrambe puntassero alla stessa stringa. Quindi piccolaPeste puntava la sua var locale a nil, ma questo non ha avuto nessun effetto sulla var al di fuori del metodo.

Valori di Ritorno

Potresti aver notato che alcuni metodi ti restituiscono qualcosa quando li chiami. Per esempio gets restituisce una stringa (la stringa digitata a riga di comando), e il metodo + in 5+3, (che è una scorciatoia per scrivere 5.+(3)) restituisce 8. I metodi aritmetici per i numeri restituiscono dei numeri, e i metodi aritmetici per le stringhe restituiscono delle stringhe.

E' importante capire la differenza fra i metodi che restituiscono un valore dove il metodo è stato chiamato e il programma che scrive informazioni sul tuo schermo, come col metodo puts. Nota che 5+3 restituisce 8; non stampa 8.

Ma allora, cosa restituisce puts? Non ce ne siamo mai interessati prima, ma ora proviamo a capirlo:

valoreRestituito = puts 'Questo puts ha restituito:'
puts valoreRestituito
Questo puts ha restituito:
nil

Quindi il primo puts ha restituito nil. E sebbene non lo abbiamo testato, anche il secondo puts restituisce la stessa cosa; puts restituisce sempre nil. Ogni metodo deve restituire qualcosa, fosse anche solo nil.

Prenditi una piccola pausa e scrivi un programma per capire cosa restituiva muggito.

Sorpreso? Bene, ecco come funziona: il valore restituito da un metodo è semplicemente l'ultima linea del metodo. Nel caso di muggito, quest vuol dire che esso restituisce puts 'muuuuuuu...'*numeroDiMuggiti, che è semplicemente nil dal momento che puts restituisce sempre nil. Se avessimo voluto che tutti i nostri metodi avessero restituito la stringa 'yellow submarine', avremmo semplicemente dovuto mettere quello alla fine di essi:

def muggito numeroDiMuggiti
  puts 'muuuuuuu...'*numeroDiMuggiti
  'yellow submarine'
end

x = muggito 2
puts x
muuuuuuu...muuuuuuu...
yellow submarine

Ora proviamo nuovamente quell'esperimento psicologico, ma questa volta scriviamo un metodo che chieda la domanda al posto nostro. Avrà bisogno di prendere la domanda come parametro, e restituire true se hanno risposto si e false se hanno risposto no. (Anche se la maggior parte delle volte ignoreremo la risposta, è comunque una buona idea che il nostro metodo la restituisca. In questo modo possiamo usarlo anche per la domanda sulla pipì a letto). Inoltre abbrevierò l'introduzione e il resoconto così che sia più semplice da leggere:

# encoding: utf-8
def chiedi domanda
  rispValida = false
  while (not rispValida)
    puts domanda
    risposta = gets.chomp.downcase
    
    if (risposta == 'si' or risposta == 'no')
      rispValida = true
      if risposta == 'si'
        risposta = true
      else
        risposta = false
      end
    else
      puts 'Per favore rispondi "si" o "no".'
    end
  end
  
  risposta  #  Questo è quello che restituiamo (true o false).
end

puts 'Ciao, e grazie per...'
puts

chiedi 'Ti piacciono i tacos?'      #  Ignoriamo questo valore di ritorno.
chiedi 'Ti piacciono i burritos?'
bagnaLetto = chiedi 'Fai la pipì a letto?'  #  Salviamo questo valore di ritorno.
chiedi 'Ti piacciono i chimichangas?'
chiedi 'Ti piacciono i sopapillas?'
chiedi 'Ti piacciono i tamales?'
puts 'Solo qualche altra domanda...'
chiedi 'Ti piace bere l\'orzata?'
chiedi 'Ti piacciono i flautas?'

puts
puts 'RESOCONTI:'
puts 'Grazie per...'
puts
puts bagnaLetto
Ciao e grazie per...

Ti piacciono i tacos?
si
Ti piacciono i burritos?
si
Fai la pipì a letto?
no way!
Per favore rispondi "si" o "no".
Fai la pipì a letto?
NO
Ti piacciono i chimichangas?
si
Ti piacciono i sopapillas?
si
Ti piacciono i tamales?
si
Solo qualche altra domanda...
Ti piace bere l'orzata?
si
Ti piacciono i flautas?
si

RESOCONTO:
Grazie per...

false

Non male, eh? Siamo stati in grado di aggiungere altre domande (e aggiungere domande ora è facile), ma il nostro programma è comunque più breve! E' un miglioramento importante — il sogno di ogni pigro programmatore.

Un Altro Esempione

Penso che un altro esempio sarebbe molto utile. Lo chiameremo englishNumber (numero in inglese, NdC), Dovrà prendere un numero, come 22, e quindi restituire la versione in italiano di esso (in questo caso, la stringa 'twenty-two'). Per adesso, facciamolo funzionare solo con gli interi da 0 a 100.

(NOTA: Questo metodo usa il nuovo comando return per restituire un valore da un metodo prima della sua ultima riga di codice, e introduce una nuova possibilità nel branching: elsif. Dovrebbe essere chiaro dal contesto come funziona).
[NdC: il codice di questo programma non l'ho tradotto per non complicarlo eccessivamente in quanto le regole per scrivere i numeri in lettere in italiano sono più complesse che in inglese.]

# encoding: utf-8
def englishNumber number
  #  Vogliamo sono numeri compresi tra  0 e 100.
  if number < 0
    return 'Per favore inserisci un numero maggiore o uguale a 0.'
  end
  if number > 100
    return 'Per favore inserisci un numero minore o uguale a 100.'
  end

  numString = ''  #  Questa è la stringa che restituiremo.

  #  "left" è quanto del numero ci rimane da scrivere.
  #  "write" è la parte del numero che stiamo scrivendo in questo momento.
  #  write e left... capito?  :)
  left  = number
  write = left/100          # Quante centinaia (hundreds) restano da scrivere?
  left  = left - write*100  # Sottraiamo queste centinaia

  if write > 0
    return 'one hundred'
  end

  write = left/10          #  Quante decine (tens) restano da scrivere?
  left  = left - write*10  #  Sottraiamo queste decine.

  if write > 0
    if write == 1  #  Uh-oh...
      #  Siccome non possiamo scrivere "tenty-two" al posto di "twelve",
      #  dobbiamo considerare delle eccezioni per i numeri da 11 a 19.
      if    left == 0
        numString = numString + 'ten'
      elsif left == 1
        numString = numString + 'eleven'
      elsif left == 2
        numString = numString + 'twelve'
      elsif left == 3
        numString = numString + 'thirteen'
      elsif left == 4
        numString = numString + 'fourteen'
      elsif left == 5
        numString = numString + 'fifteen'
      elsif left == 6
        numString = numString + 'sixteen'
      elsif left == 7
        numString = numString + 'seventeen'
      elsif left == 8
        numString = numString + 'eighteen'
      elsif left == 9
        numString = numString + 'nineteen'
      end
      #  Siccome abbiamo già considerato le unità,
      #  non abbiamo nient'altro da scrivere.
      left = 0
    elsif write == 2
      numString = numString + 'twenty'
    elsif write == 3
      numString = numString + 'thirty'
    elsif write == 4
      numString = numString + 'forty'
    elsif write == 5
      numString = numString + 'fifty'
    elsif write == 6
      numString = numString + 'sixty'
    elsif write == 7
      numString = numString + 'seventy'
    elsif write == 8
      numString = numString + 'eighty'
    elsif write == 9
      numString = numString + 'ninety'
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left  #  Quante unità restano da scrivere?
  left  = 0     #  Sottraiamo tutte queste unità.

  if write > 0
    if    write == 1
      numString = numString + 'one'
    elsif write == 2
      numString = numString + 'two'
    elsif write == 3
      numString = numString + 'three'
    elsif write == 4
      numString = numString + 'four'
    elsif write == 5
      numString = numString + 'five'
    elsif write == 6
      numString = numString + 'six'
    elsif write == 7
      numString = numString + 'seven'
    elsif write == 8
      numString = numString + 'eight'
    elsif write == 9
      numString = numString + 'nine'
    end
  end

  if numString == ''
    #  L'unico caso in cui "numString" è vuota è quando
    #  "number" è 0.
    return 'zero'
  end

  #  Se siamo arrivati fin qui, allora avevamo un numero compreso fra 0 e 100
  #  quindi ora non ci rimane che restituire "numString".
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)
zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred

Uhm, ci sono sicuramente un po' di cose di questo programma che non mi piacciono. Primo, ha troppa ripetizione. Secondo, non gestisce numeri maggiori di 100. Terzo, ci sono troppi casi speciali, troppi return. Usiamo qualche array e cerchiamo di ripulirlo un po':

# encoding: utf-8
def englishNumber number
  if number < 0  #  No numeri negativi.
    return 'Per favore inserisci un numero che non sia negativo.'
  end
  if number == 0
    return 'zero'
  end

  #  Nessun caso particolare!  Nessun return!

  numString = ''  #  Questa è la stringa che restituiremo.

  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']

   # "left" è quanto del numero ci rimane da scrivere.
   # "write" è la parte del numero che stiamo scrivendo in questo momento.
   # write e left... capito?  :)    
  left  = number
  write = left/100          # Quante centinaia (hundreds) restano?
  left  = left - write*100  # Sottraiamo queste centinaia.

  if write > 0
    #  Ed ora un espediente molto astuto:
    hundreds  = englishNumber write
    numString = numString + hundreds + ' hundred'
    # Si chiama "ricorsione". Che cosa ho appena fatto?
    # Ho detto a questo metodo di chiamare se stesso, ma con "write"  
    # al posto di "number". Ricorda che "write" è (al momento) il
    # numero di centinaia che dobbiamo scrivere.  Dopo aver aggiunto  
    # "hundreds" a "numString", aggiungiamo la stringa 
    # ' hundred' dopo di essa. Così, per esempio, se inizialmente avessimo 
    #  chiamato englishNumber con 1999 (quindi "number" = 1999), 
    #  allora a questo punto "write" sarebbe pari a 19, e "left"  
    #  sarebbe pari a 99. 
    # 
    # La cosa più pigra, a questo punto, è fare in modo che englishNumber
    # scriva il 'nineteen' per noi, dopodiché noi scriviamo ' hundred',
    # quindi e tutto il resto di englishNumber scriverà 'ninety-nine'.

    if left > 0
      #  Così non scriviamo 'two hundredfifty-one'...
      numString = numString + ' '
    end
  end

  write = left/10          #  Quante decine (tens) ci rimangono da scrivere?
  left  = left - write*10  #  Sottraiamo tutte queste decine.

  if write > 0
    if ((write == 1) and (left > 0))
      #  Siccome non possiamo scrivere "tenty-two" al posto di "twelve",
      #  dobbiamo considerare i numeri da 11 a 19 dei casi particolari.
      numString = numString + teenagers[left-1]
      #  Il "-1" è perché teenagers[3] è 'fourteen', non 'thirteen'.

      #  Siccome le unità sono già considerate nei casi particolari,
      #  non abbiamo nient'altro da scrivere.
      left = 0
    else
      numString = numString + tensPlace[write-1]
      #  Il "-1" è perché tensPlace[3] è 'forty', non 'thirty'.
    end

    if left > 0
      #  Così non scriviamo 'sixtyfour'...
      numString = numString + '-'
    end
  end

  write = left  # Quante unità (ones) restano da scrivere?
  left  = 0     #  Sottraiamo queste unità.

  if write > 0
    numString = numString + onesPlace[write-1]
    #  Il "-1" è perché onesPlace[3] è 'four', non 'three'.
  end

  #  Ora non ci resta che restituire "numString"...
  numString
end

puts englishNumber(  0)
puts englishNumber(  9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)
puts englishNumber(101)
puts englishNumber(234)
puts englishNumber(3211)
puts englishNumber(999999)
puts englishNumber(1000000000000)
zero
nine
ten
eleven
seventeen
thirty-two
eighty-eight
ninety-nine
one hundred
one hundred one
two hundred thirty-four
thirty-two hundred eleven
ninety-nine hundred ninety-nine hundred ninety-nine
one hundred hundred hundred hundred hundred hundred

Ahhhh.... Così va molto, molto meglio. Il programma è piuttosto denso, ed è per questo che ci ho incluso così tanti commenti. Funziona anche per numeri grandi... sebbene non così bene come vorremmo. Per esempio, penso che 'one trillion' sarebbe un più bel numero da restituire rispetto a quell'ultimo numero, o anche 'one million million' (sebbene tutti e tre siano formalmente corretti). Ora che ci penso, potresti esercitarti a modificare il programma in questo modo proprio adesso...

Un Po' di Cose da Provare

  • Migliora il programma englishNumber. Prima di tutto, considera le migliaia (thousands). Cosè che restituisca 'one thousand' al posto di 'ten hundred' e 'ten thousand' al posto di 'one hundred hundred'.
  • Migliora il programma englishNumber ancora un po'. Ora considera i milioni (millions), così da ottenere 'one million' al posto di 'one thousand thousand'. Poi prova a considerare anche miliardi (billions) e trilioni (trillions). Quanto in altro riesci ad arrivare?
  • E che mi dici di weddingNumber (numero di matrimonio)? dovrebbe funzionare più o meno come englishNumber, eccetto che dovrebbe inserire la parola "and" in mezzo a tutti i numeri, restituendo cose del tipo 'nineteen hundred and seventy and two', o come dovrebbero sembrare i numeri scritti sugli inviti ai matrimoni. Ti darei qualche esempio in più, ma non li capisco bene nemmeno io. Potresti contattare un consulente di nozze per farti aiutare. NdC: questo è solo uno scherzo dell'autore, non devi realizzarlo davvero! ;-) 
  • "novanta-nine bottles of beer..." Usando englishNumber e il nostro vecchio programma, scrivi il testo di questa canzone nel modo giusto questa volta (coi numeri scritti in lettere). Punisci il tuo computer: fallo partire a 9999. (Non prendere un numero troppo grande, comunque, perché scrivere tutta la canzone sullo schermo potrebbe richiedere un po'... Centomila bottiglie richiedono qualche istante, se ne vuoi un milione o più, assieme al computer potresti punirti anche da solo!)
  • E i numeri in italiano? Un po' di sano patriottismo, e che diamine! Prova a scrivere il programma "italiaNumber" che, dato un numero in cifra lo restituisca in lettere, questa volta in italiano. 
    Suggerimento: il metodo chop serve a eliminare l'ultima lettera di una stringa, per esempio ciao.chop restituisce 'cia'. Altri metodi delle stringhe sono disponibili nella documentazione ufficiale.
  • Ora puoi scrivere un programma per la canzone delle bottiglie di birra anche in italiano!

Complimenti! A questo punto, sei un vero programmatore! Hai imparato tutto ciò che ti serva per scrivere programmi enormi partendo da zero. Se ti sono venute delle idee per tuoi programmi originali, prova pure a scriverli!

Ovviamente, costruire ogni cosa da zero tende a essere un processo abbastanza lento. Perché spendere così tanto tempo per riscrivere del codice che qualcun altro ha già scritto? Vuoi che il tuo programma sia in grado di inviare delle email? Vuoi che sia in grado di caricare e salvare file sul tuo computer? E che ne diresti di scrivere le pagine di un tutorial in cui gli esempi di codice sono già testati? ;)
Ruby ha tanti e diversi tipi di oggetti che possiamo sfruttare per scrivere programmi migliori e più velocemente.

Le soluzioni di tutti gli esercizi proposti sono disponibili anche nel Manuale delle Soluzioni in Italiano.


Commenti

La sezione commenti è messa a disposizione per consentirti di scambiare idee e consigli con gli altri studenti, fanne buon uso!
Nota bene: se vuoi condividere del codice puoi utilizzare i tag <pre> e <code>, così:

<pre><code>
saluto = 'ciao'
puts saluto
</code></pre>