Ruby on Rails Ghid de studiu Blocuri, Procs și Lambdas

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.

blocuri

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 Randamentputerea lui. Utilizările blocurilor în Ruby sunt nesfârșite și le folosim frecvent în codul nostru.


procs

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.


Lambda

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


Concluzie

În acest ghid de studiu, am acoperit diferențele cheie dintre blocuri, procs și Lambdas:

  • Blocurile sunt pentru o singură utilizare.
  • Procs există ca obiecte.
  • Lambdas au o verificare strictă a argumentelor.

Pentru o analiză mai aprofundată, vă recomandăm următoarele resurse:

  • Rails Ghiduri de studiu aici pe Nettuts+
  • Documentația Ruby Proc
  • Programarea Ruby 1.9
  • Metroprogramarea Ruby: Programul ca și profesioniștii din Ruby
Cod