Ruby este o limbă cu un set de caracteristici puternice - cele mai puternice fiind, fără îndoială, Blocks, Procs și Lambdas. Pe scurt, aceste caracteristici vă permit să transmiteți codul unei metode și să executați codul respectiv ulterior. În ciuda utilizării regulate a acestor caracteristici, mulți dezvoltatori nu înțeleg pe deplin diferențele subtile dintre ele.
Ghiduri de studiu: Atunci când aplicați pentru un program de lucru, veți fi adesea prezentat un test care intenționează să vă determine nivelul de cunoștințe și experiență într-un anumit subiect. Diferitele articole din această serie oferă soluții concise la întrebările pe care le-ați putea aștepta să le vedeți în astfel de teste.Un bloc este un cod care este implicit transferat unei metode prin utilizarea fie a acoladelor curl, ...
, sau ... termină
sintaxă. Este o convenție comună de folosit ...
pentru blocuri cu o singură linie și ... termină
pentru blocuri cu mai multe linii. De exemplu, următoarele blocuri sunt în mod funcțional aceleași:
array = [1,2,3,4] array.map! nu | n | n * n end => [1, 4, 9, 16] array = [1,2,3,4] array.map! | n | n * n => [1, 4, 9, 16]
Magia din spatele unui bloc este Randament
cuvinte cheie; ea îndepărtează executarea metodei de apelare pentru a evalua blocul. Rezultatul blocului, dacă este cazul, este apoi evaluat de orice cod rămas din metodă. Randament
instrucțiunea poate accepta, de asemenea, parametri, care apoi sunt transmise și evaluate în cadrul blocului. Legând acest lucru împreună, un exemplu simplu al Hartă!
Metoda de mai sus ar fi următoarea:
clasă Array def hartă! auto.each_with_index face | valoare, index | auto [index] = randament (valoare) capăt sfârșit sfârșit
Această reprezentare simplă a Hartă!
cheamă each_with_index
și înlocuiește elementul de la indexul dat cu rezultatul blocului. În timp ce acest lucru este un exemplu trivial de utilizare a blocurilor, vă ajută să le arătați Randament
puterea lui. Utilizările blocurilor în Ruby sunt nesfârșite și le folosim frecvent în codul nostru.
Exemplul de mai sus demonstrează o limitare minoră a blocurilor: acestea sunt sintaxă și sunt disponibile. Trebuie să reintroducem blocuri de fiecare dată când le reutilizăm pe diferite tablouri, dar putem stoca un bloc pentru o utilizare ulterioară utilizând Ruby Proc Object. Putem stoca un Proc într-o variabilă și apoi să o transmitem în mod explicit unei metode care acceptă un obiect care poate fi sunat. Rescrierea exemplului de mai sus ca Proc ar arăta astfel:
number_squared = Proc.new | n | n * n
Să ne modificăm Hartă!
metoda de acceptare și apelarea obiectului Proc:
Clasa Array def harta! (proc_object) auto.each_with_index nu | valoare, index | auto [index] = proc_object.call (valoare) end end end array = [1,2,3,4] array.map! (număr_squared) => [1, 4, 9, 16]
Luați notă că nu mai folosim Randament
cuvinte cheie; în schimb, folosim direct apel
pe obiectul Proc, trecând valoarea din matrice. Primim același rezultat ca înainte, dar stocăm blocul nostru într-o variabilă pentru a reutiliza ulterior.
Funcția Lambda sunt aproape identice cu Procs, dar cu două diferențe cheie. Mai întâi, o lambda verifică numărul de argumente pe care le primește și o returnează ArgumentError
dacă nu se potrivesc. De exemplu:
l = lambda "Eu sunt o lambda" l.call => "Sunt o lambda" l.call ('arg') ArgumentError:
În al doilea rând, lambda-urile oferă randamente diminutive - ceea ce înseamnă că atunci când un Proc întâlnește o declarație de întoarcere în execuția lui, el oprește metoda și returnează valoarea furnizată. Lambdas, pe de altă parte, returnează valoarea metodei, permițându-i să continue:
def proc_math Proc.new întoarcere 1 + 1 .call întoarcere 2 + 2 end def lambda_math lambda întoarcere 1 + 1 .call întoarcere 2 + 2 end proc_math # => 2 lambda_math # => 4
După cum puteți vedea proc_math
afișează declarația de returnare din interiorul Proc și returnează valoarea 2
. In contrast, lambda_math
ignoră declarația de returnare și evaluează în schimb 2 + 2.
O notă finală: Ruby 1.9 introduce noua sintaxă lambda "stabby" (reprezentată cu ->), care este identică funcțional cu sintaxa lambda tradițională, dar sintaxa "stabby" este mult mai curată.
În acest ghid de studiu, am acoperit diferențele cheie dintre blocuri, procs și Lambdas:
Pentru o analiză mai aprofundată, vă recomandăm următoarele resurse: