Ruby este una dintre cele mai populare limbi folosite pe web. Am inceput o noua serie de screencast-uri aici pe Nettuts +, care va va prezenta Ruby, precum si marile cadre si instrumente care merg impreuna cu dezvoltarea Ruby. În acest capitol vom vorbi despre blocuri și iteratori.
În ultima lecție, am vorbit despre bucle. De fapt, nu veți folosi buclele prea des în Ruby, din cauza unei caracteristici numite blocuri (și - ca urmare a blocurilor - iteratori). Pentru a vă reîmprospăta memoria, consultați cele două metode de mai jos (puteți încerca acest lucru în IRB):
nume = "Joe" name.reverse # => "eoJ" nume.concat ("instalatorul") # => "Joe instalatorul"
După cum știți, parantezele după apelul metodic sunt de obicei opționale. Vom învăța astăzi când sunt necesare.
Deci, aici sunt părțile unei metode de apel:
Nume
de mai sus.inversa
sau concat
de mai sus." instalatorul"
în al doilea exemplu de mai sus.Primele trei părți sunt necesare, evident. Argumentele și blocul de coduri sunt opționale. Ce este acest bloc de cod? Uitați-vă la acest exemplu și apoi o vom discuta:
site-uri = ["net", "psd", "mobile"] sites.map! face | site | site + = ".tutsplus.com" site-uri finale # => ["net.tutsplus.com", "psd.tutsplus.com", "mobile.tutsplus.com"]
În acest caz, matricea site-uri
este receptorul; metoda este Hartă!
. Mai avem blocul. Dacă blocul se află pe mai multe linii, puteți utiliza cuvintele cheie do
și Sfârșit
pentru ao delimita. Dacă o puneți pe o singură linie, puteți utiliza bretele curbate (acestea lucrează și pentru blocuri cu mai multe linii).
După deschiderea blocului, avem parametrii de bloc, în interiorul conductelor ( |
). Ceea ce depinde într-adevăr de metoda pe care o executați. Cea mai obișnuită utilizare a blocurilor este în metodele iterator, astfel încât parametrul bloc va fi elementul curent în buclă. Dacă sună mai degrabă abstractă, vom face câteva exemple.
Vom începe cu uita-te la iteratori de matrice, deoarece acestea sunt cel mai frecvent looped peste lucru.
În loc să utilizați o buclă pentru, probabil că veți folosi fiecare
:
site - uri ["net", "psd", "mobile"] site - uri pune "# site .tutsplus.com" # net.tutsplus.com # psd.tutsplus.com # mobile.tutsplus.com
Acest lucru este ca și cum ați face o buclă; unul câte unul, fiecare articol în site-uri
va fi atribuit parametrului bloc teren
; atunci codul din interiorul blocului va fi executat.
În cazul în care sunteți curios, fiecare
metoda returnează matricea originală.
Uneori, veți dori să returnați o valoare din bloc. Nu este greu de făcut dacă folosiți metoda potrivită.
# își asumă site-urile deasupra site-urilor = sites.map do | s | "# s .tutsplus.com" se încheie
Hartă
metoda colectează orice valori sunt returnate din fiecare iterație a blocului. Apoi, o matrice din aceste valori este returnată din metodă. În acest caz, îl reassignăm site-uri
variabilă la noua matrice.
Există o modalitate mai bună de a face acest lucru, totuși. Mai multe metode Ruby au duplicate cu semnul exclamării (sau bang); aceasta înseamnă că sunt distructive: ele înlocuiesc valoarea pe care lucrează. Astfel, cele de mai sus s-ar putea face astfel:
sites.map! | site_prefix | "# site_prefix .tutsplus.com"
Acum, site-uri
va fi matricea valorilor returnate din bloc.
Mai mult decât arrays au metode iterator, deși. Numerele sunt destul de reci ori
metodă:
5.times nu | i | pune "Numărul buclă # i" sfârșitul # Numărul buclă 0 # Buclă numărul 1 # Buclă numărul 2 # Buclă numărul 3 # Buclă numărul 4
Pe măsură ce continuați să codificați Ruby, veți găsi o mulțime de metode utile care utilizează blocuri. Acum, să vedem cum să ne creăm propriile blocuri.
Acum, că sunteți familiarizați cu utilizarea blocurilor, să vedem cum să scrieți metode care să profite de ele. Iată două alte tidbits de bloc pe care nu le-ați învățat încă:
Iată ce se întâmplă să numiți o metodă care ia un blocaj. În spatele scenei, Ruby execută un anumit cod de metodă, apoi cedează codului de bloc. După aceea, controlul este returnat metodei. Hai să verificăm.
Deoarece majoritatea funcțiilor simple iteratoare sunt construite în Ruby, vom "rescrie" unul dintre acestea. Să facem asta fiecare
Metoda pe matrice:
clasa Array def each2 i = 0; în timp ce eu [i] dăruiesc eu [i] i + = 1 capăt de sfârșit de sine
După cum puteți vedea, aceasta este doar o metodă normală. Amintiți-vă că în cadrul unei metode de instanță de sine
cuvântul cheie se referă la instanța clasei, în acest caz, mulțime
. În interiorul metodei, folosim o buclă în timp pentru a trece peste elementele din matrice. Apoi, în interiorul buclă, vom folosi Randament
cuvinte cheie. Noi o trecem sine [i]
; care va deveni parametrul de bloc. După asta, noi creștem eu
pentru buclă și continuați.
Dacă am vrut ca această metodă să returneze gama de valori pe care le-a returnat blocul, am putea să capturăm valoarea returnată de Randament
și returnează asta, în loc de de sine
, vom returna acea matrice.
clasa Array def each2_returning_new_values i = 0; new_vals = []; în timp ce eu [i] new_vals [i] = randamentul auto [i] i + = 1 sfârșitul sfârșitului new_vals
Hai să terminăm vorbind despre metode. Știm că folosirea parantezelor este opțională ... de cele mai multe ori. Iată când trebuie să folosiți paranteza atunci când apelați metoda.
Uneori, veți avea atât parametrii metodei, cât și un bloc.
obj.some_method "param" | x | #block code here
Ceea ce am terminat nu va funcționa; trebuie să folosim paranteze în acest caz, deoarece altfel blocul este asociat cu ultimul parametru. Acest lucru este valabil numai dacă utilizați bretele curbate pentru a delimita blocul; dacă utilizați do
- Sfârșit
, parantezele nu sunt necesare.
O altă paranteză de timp este necesară atunci când treceți un hash literal (nu o variabilă care indică o hash) ca primul parametru al metodei. Ruby va crede că este un blocaj, din cauza coaselor curbate
arr.push : nume => "Andrew" # Eșuat! arr.push (: nume => "Andrew") # Pasează