Ruby pentru începători iteratori și blocuri

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.


Ajunge din urmă

  • Lectia 1: Instalarea Ruby și începutul
  • Lectia 2: Variabile, tipuri de date și fișiere 
  • Lecția 3: Lucrul cu clasele
  • Lecția 4: Condiții și bucle
  • Lecția 5: Iteratori și blocuri

Vizualizați ecranul


blocuri

Î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:

  • Obiectul care primește metoda; Nume de mai sus.
  • Punctul.
  • Numele metodei; inversa sau concat de mai sus.
  • Argumentele; " instalatorul" în al doilea exemplu de mai sus.
  • Blocul de coduri; Rămâneți aproape!

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.


iteratori

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.


Blocuri de construcție

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ă:

  • Parametrii blocului nu sunt necesari; puteți scrie un bloc care nu le folosește.
  • Blocurile ele însele pot fi opționale. Puteți scrie o funcție care funcționează cu sau fără blocuri.

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

Metode, revizuite

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ă
Cod