Ruby è una delle lingue più popolari utilizzate sul web. Abbiamo avviato una nuova serie di screencast qui su Nettuts + che ti introdurrà a Ruby, oltre ai grandi framework e strumenti che accompagnano lo sviluppo di Ruby. In questo capitolo parleremo di blocchi e iteratori.
Nell'ultima lezione, abbiamo parlato di loop. In realtà non userete i loop troppo spesso in Ruby, a causa di una funzione chiamata blocchi (e-come risultato di blocchi-iteratori). Per aggiornare la memoria, guarda le due seguenti chiamate di metodo (puoi provare questo in IRB):
name = "Joe" name.reverse # => "eoJ" name.concat ("the Plumber") # => "Joe the Plumber"
Come sai, le parentesi dopo la chiamata al metodo sono solitamente facoltative. Impareremo oggi quando sono richiesti.
Quindi, ecco le parti di una chiamata al metodo:
nome
sopra.inverso
o concat
sopra." l'idraulico"
nel secondo esempio sopra.Le prime tre parti sono obbligatorie, ovviamente. Gli argomenti e il blocco di codice sono facoltativi. Cos'è questo blocco di codice? Guarda questo esempio e poi ne discuteremo:
sites = ["net", "psd", "mobile"] sites.map! do | site | site + = ".tutsplus.com" end sites # => ["net.tutsplus.com", "psd.tutsplus.com", "mobile.tutsplus.com"]
In questo caso, la matrice siti
è il ricevitore; il metodo è carta geografica!
. Quindi abbiamo il blocco. Se il blocco è su più righe, puoi utilizzare le parole chiave fare
e fine
delimitarlo. Se lo metti su una singola riga, puoi usare le parentesi graffe (anche queste funzionano per i blocchi multi-linea).
Dopo l'apertura del blocco, abbiamo i parametri del blocco, all'interno dei tubi ( |
). Ciò dipende dal metodo che stai eseguendo. L'uso più comune dei blocchi è nei metodi iteratori, quindi il parametro di blocco sarà l'elemento corrente nel ciclo. Se questo suona piuttosto astratto, faremo alcuni esempi.
Inizieremo osservando gli iteratori degli array, perché sono la cosa più frequentemente incastrata.
Invece di usare un ciclo for, probabilmente lo userai ogni
:
sites = ["net", "psd", "mobile"] sites.each | site | inserisce "# site .tutsplus.com" # net.tutsplus.com # psd.tutsplus.com # mobile.tutsplus.com
Questo è come fare un ciclo for; uno per uno, ogni oggetto in siti
sarà assegnato al parametro di blocco posto
; quindi, il codice all'interno del blocco verrà eseguito.
Nel caso in cui sei curioso, il ogni
metodo restituisce l'array originale.
A volte, vorrai restituire un valore dal blocco. Non è difficile da fare, se usi il metodo giusto.
# presuppone che i siti sopra sites = sites.map facciano | s | "# s .tutsplus.com" fine
Il carta geografica
metodo raccoglie tutti i valori restituiti da ogni iterazione del blocco. Quindi, una matrice di tali valori viene restituita dal metodo. In questo caso, stiamo riassegnando il siti
variabile al nuovo array.
C'è un modo migliore per farlo, però. Diversi metodi Ruby hanno duplicati con il punto esclamativo (o bang); questo significa che sono distruttivi: sostituiscono il valore su cui stanno lavorando. Quindi quanto sopra potrebbe essere fatto in questo modo:
sites.map! | site_prefix | "# site_prefix .tutsplus.com"
Adesso, siti
sarà la matrice di valori restituiti dal blocco.
Tuttavia, più che semplici matrici hanno metodi iteratori. I numeri sono piuttosto interessanti volte
metodo:
5.times do | i | inserisce "Numero loop # i" fine # Numero loop 0 # Numero loop 1 # Numero loop 2 # Numero loop 3 # Numero loop 4
Continuando a scrivere Ruby, troverai molti metodi utili che usano i blocchi. Ora, vediamo come creare i nostri blocchi.
Ora che hai familiarità con l'utilizzo dei blocchi, vediamo come scrivere metodi che ne traggano vantaggio. Ecco altre due curiosità di blocco che non hai ancora imparato:
Ecco cosa succede quando chiami un metodo che prende un blocco. Dietro le quinte, Ruby sta eseguendo un codice di metodo, quindi, cedendo al codice di blocco. Successivamente, il controllo viene restituito al metodo. Controlliamolo.
Poiché la maggior parte delle semplici funzioni di iteratore sono incorporate in Ruby, "riscriviamo" una di queste. Facciamo il ogni
metodo sugli array:
class Array def each2 i = 0; mentre self [i] produce self [i] i + = 1 end self end end
Come puoi vedere, questo è solo un metodo normale. Ricorda che all'interno di un metodo di istanza, il se stesso
parola chiave si riferisce all'istanza della classe, in questo caso, schieramento
. All'interno del metodo, stiamo usando un ciclo while per eseguire il loop sugli elementi dell'array. Quindi, all'interno del ciclo, usiamo il dare la precedenza
parola chiave. Lo stiamo passando self [i]
; che finirà per essere il parametro di blocco. Successivamente, incrementiamo io
per il ciclo e continua.
Se volessimo che questo metodo restituisse la matrice di valori restituita dal blocco, potremmo semplicemente catturare il valore restituito di dare la precedenza
e restituiscilo, invece di se stesso
, restituiamo quella matrice.
class Array def each2_returning_new_values i = 0; new_vals = []; mentre self [i] new_vals [i] = produce self [i] i + = 1 end new_vals end end
Finiamo parlando dei metodi. Sappiamo che l'uso delle parentesi è facoltativo ... il più delle volte. Ecco quando è necessario utilizzare le parentesi quando si chiama metodo.
A volte, avrai sia parametri di metodo che un blocco.
obj.some_method "param" | x | # codice di blocco qui
Quello che ho appena fatto non funzionerà; abbiamo bisogno di usare parentesi in questo caso, perché altrimenti il blocco è associato all'ultimo parametro. Questo è solo il caso se usi le parentesi graffe per delimitare il blocco; se usi fare
- fine
, le parentesi non sono obbligatorie.
L'altra parentesi temporale è necessaria quando si passa un hash letterale (non una variabile che punta a un hash) come primo parametro del metodo. Ruby penserà che sia un blocco, a causa della parentesi graffa
arr.push : name => "Andrew" # Fallisce! arr.push (: name => "Andrew") # Passa