Ruby est un langage avec un ensemble de fonctionnalités puissantes - les plus puissantes étant sans aucun doute Blocks, Procs et Lambdas. En bref, ces fonctionnalités vous permettent de transmettre du code à une méthode et de l'exécuter ultérieurement. Malgré l'utilisation régulière de ces fonctionnalités, de nombreux développeurs ne comprennent pas parfaitement les différences subtiles qui les séparent..
Guides d'étude: Lorsque vous postulez pour un emploi en programmation, vous serez souvent confronté à un questionnaire visant à déterminer votre niveau de connaissances et votre expérience dans un sujet donné. Les différents articles de cette série apportent des solutions condensées aux questions que vous pourriez vous attendre à voir lors de tels tests..Un bloc est un code qui est implicitement transmis à une méthode via l’utilisation de deux accolades., …
, ou faire… fin
syntaxe. C'est une convention commune d'utiliser …
pour des blocs d'une seule ligne, et faire… fin
pour des blocs multilignes. Par exemple, les blocs suivants sont fonctionnellement identiques:
array = [1,2,3,4] array.map! faire | n | n * n end => [1, 4, 9, 16] array = [1,2,3,4] array.map! | n | n * n => [1, 4, 9, 16]
La magie derrière un bloc est la rendement
mot-clé; il diffère l'exécution de la méthode d'appel afin d'évaluer le bloc. Le résultat du bloc, le cas échéant, est ensuite évalué par tout code restant dans la méthode. le rendement
instruction peut également accepter des paramètres, qui sont ensuite transmis et évalués dans le bloc. Lier cela ensemble, un exemple simple de la carte!
La méthode ci-dessus serait la suivante:
class Array def map! self.each_with_index do | valeur, index | self [index] = rendement (valeur) fin fin fin
Cette représentation simple de carte!
appelle le chaque_avec_index
méthode et remplace l'élément de l'index donné par le résultat du bloc. Bien que ce soit un exemple trivial d’utilisation de bloc, il est utile de montrer rendement
le pouvoir. Les utilisations de blocs dans Ruby sont infinies, et nous les utilisons fréquemment dans notre code.
L'exemple ci-dessus illustre une limitation mineure des blocs: ils sont syntaxiques et jetables. Nous devons ressaisir des blocs chaque fois que nous les réutilisons sur différents tableaux, mais nous pouvons stocker un bloc pour une utilisation ultérieure en utilisant l'objet Ruby Proc. Nous pouvons stocker un Proc dans une variable, puis le transmettre explicitement à toute méthode qui accepte un objet appelable. Réécrire l'exemple ci-dessus en tant que Proc ressemblerait à ceci:
number_squared = Proc.new | n | n * n
Modifions notre carte!
méthode pour accepter et appeler l'objet Proc:
class Array def map! (proc_object) self.each_with_index do | valeur, index | self [index] = proc_object.call (valeur) fin fin fin tableau = [1,2,3,4] array.map! (number_squared) => [1, 4, 9, 16]
Prenez note que nous n’utilisons plus le rendement
mot-clé; à la place, nous utilisons directement le appel
méthode sur l'objet Proc, en lui transmettant la valeur du tableau. Nous recevons le même résultat qu'auparavant, mais nous stockons notre bloc dans une variable pour pouvoir le réutiliser ultérieurement..
La fonction Lambda est presque identique à Procs mais avec deux différences principales. Tout d’abord, un lambda vérifie le nombre d’arguments qu’il reçoit et renvoie un ArgumentError
si elles ne correspondent pas. Par exemple:
l = lambda "Je suis un lambda" l.call => "Je suis un lambda" l.call ('arg') ArgumentError: nombre incorrect d'arguments (1 pour 0)
Deuxièmement, lambdas fournit des retours diminutifs - ce qui signifie que lorsqu'un Proc rencontre une instruction return dans son exécution, il arrête la méthode et renvoie la valeur fournie. Lambdas, d’autre part, renvoient leur valeur à la méthode, lui permettant de continuer:
def proc_math Proc.new return 1 + 1 .call return 2 + 2 end def lambda_math lambda return 1 + 1 .call return 2 + 2 end proc_math # => 2 lambda_math # => 4
Comme vous pouvez le voir proc_math
frappe l'instruction de retour à l'intérieur du Proc et renvoie la valeur de 2
. En revanche, lambda_math
ignore l'instruction de retour et évalue 2 + 2 à la place.
Une dernière remarque: Ruby 1.9 introduit la nouvelle syntaxe lambda "stabby" (représentée avec ->), qui est fonctionnellement identique à la syntaxe lambda traditionnelle, mais la syntaxe "stabby" est beaucoup plus nette..
Dans ce guide d'étude, nous avons couvert les principales différences entre Blocks, Procs et Lambdas:
Pour un examen plus approfondi, je vous recommande les ressources suivantes: