• Contenu
  • Bas de page
blog-ouidou_logoblog-ouidou_logoblog-ouidou_logoblog-ouidou_logo
  • Actualités Ouidou
  • Articles Techniques
  • Livres blancs
  • Interviews Clients
  • Interviews collaborateurs
Découvrir Ouidou
✕
No results See all results
Mise en place d’un cluster PostgreSQL avec Pgpool II

Mise en place d’un cluster PostgreSQL avec Pgpool II

3 septembre 2014
Création d’un menu en accordéon avec CSS

Création d’un menu en accordéon avec CSS

4 juin 2015
Ressources > Blocks, Proc et Lambda en Ruby

Blocks, Proc et Lambda en Ruby

Écrit par Jonathan F.

Les closures (Block, Proc & Lambda) Ruby sont l’un des aspects les plus puissants du langage. Ce sont des fonctions liées à l’environnement dans lequel elles ont été définies. Elles ont la particularité de garder l’accès à des variables présentes dans la portée de celle-ci au moment où elles sont créées mais qui peut également ne plus être dans cette portée au moment où nous appelons cette closure.

Voici un exemple qui montre que notre closure à accès à une variable locale dans l’état qu’elle avait au moment de la création de la fonction :

counter = 1 defexample variable Proc.new {variable} end a = example counter # A cet instant counter = 1 counter = 10 a.call # => 1

Contrairement à d’autres langages, ruby dispose de différentes manières de gérer ces closures. Chacune d’entre elles se comporte de façon légèrement différente, ce qui ne simplifie pas son utilisation.

Pour résumer, ces fonctions vous permettent de passer du code à une méthode et de l’exécuter à une date antérieure au sein de cette méthode.

Blocs

Pour être simple, un block est un morceau de code qui sera appelé dans la méthode à laquelle vous le fournissez. Selon les conventions il se définit entre accolade {} s’il peut être défini sur une ligne ou entre do et end s’il est multi-lignes.

defon_dit_merci_a_qui(name) yield(name) if block_given? end on_dit_merci_a_qui("bibi") { |name| puts "Merci #{name}" } on_dit_merci_a_qui("bibi") do|name| puts "Merci #{name}" end# => "Merci bibi"

En Ruby, toute fonction peut prendre un block et un seul comme argument, celui-ci sera interprété si la fonction fait appel au mot-clé yield qui évalue le block.

L’utilisation de la condition if block_given? est importante car utiliser yield dans une fonction ne recevant pas de block lève une exception LocalJumpError: no block given (yield).

Le résultat du block pourra ensuite être évalué par le restant du code de la fonction. yield peut accepter des arguments (ici name) qu’il va transmettre au block. Contrairement à yield le block ne vérifie pas le nombre d’arguments, il les ignore comme le montre l’exemple suivant :

on_dit_merci_a_qui("bibi") { |name, test| puts "Merci #{name.class} et #{test.class}" } => "Merci à String et NilClass"

Quelle classe à un block ?

defblock_class(&code) code.class end block_class {} # => Proc

Pouvons-nous réutiliser un block ultérieurement sans devoir le retaper ? Autrement dit, pouvons-nous stocker un block dans une variable ? Non ! Ce qui le rend assez limité car “jetable”. Proc et lambda vont nous permettre de faire cela.

Proc

Un proc est une instance de la classe Proc. C’est un objet qui peut être lié à une variable et réutilisé. Il se définit en appelant Proc.new ou proc suivi d’un block. Il peut également être créé en appelant la méthode to_proc d’une méthode, proc ou symbole. Il est appelé via sa méthode call.

p = Proc.new {|name| puts "Merci #{name}" } @staff =["bibi", "chuck", "norris"]defmerci_tout_le_monde(proc) @staff.each do|name| proc.call(name) endend merci_tout_le_monde(p) # => Merci bibi# => Merci chuck# => Merci norrisdefmerci_qui(proc) proc.call(@staff.first) end merci_qui(p) # => Merci bibi

Notre proc est donc bien réutilisable au sein de différentes méthodes. Lorsqu’un proc est appelé via sa fonction call, et qu’il rencontre une instruction de retour (return) dans son exécution, il arrête la méthode et renvoie la valeur. De ce fait :

defmerci_qui(name) p = Proc.new {|name|return "Merci #{name}" } p.call(name) return "Merci à tous" end merci_qui("bibi") # => Merci bibi

L’utilisation de l’instruction de retour return au sein d’un bloc dépend du contexte dans lequel il est initialisé, c’est la raison pour laquelle notre proc est créé dans le scope de la méthode qui sera appelée. Retrouvez plus d’explications sur ce comportement via cet échange de stackoverflow.

Comme le block, un proc ne vérifie pas le nombre d’arguments, il les ignore :

p.call("bibi", "chuck") # => Merci bibi

La classe d’un proc est naturellement Proc.

Lambda

La fonction lambda se définie par l’appel de son nom de fonction suivie d’un block :

l = lambda { |name| puts "Merci #{name}" } l.call("bibi") # => Merci bibi

Depuis la version 1.9 de Ruby, la syntaxe s’est simplifiée :

l =-> (name) { puts "Merci #{name}" } l.call("bibi") # => Merci bibi

La fonction lambda est similaire à proc à l’exception de deux règles : – il vérifie le nombre d’arguments qui lui est fourni et renvoie un ArgumentError si celui ne correspond pas :

l.call("bibi", "chuck") # => ArgumentError: wrong number of arguments (2 for 1)
  • il n’interrompt pas l’exécution de la méthode dans lequel il est appelé même s’il rencontre une instruction de retour (return) :

l =-> (name) { return « Merci #{name} » } defmerci_qui(lambda) lambda.call(« bibi ») return « Merci à tous » end merci_qui(l) => Merci à tous

La classe d’un lambda est Proc.

L’opérateur unaire &

L’opérateur & est souvent utilisé en Ruby avec les fonctions définies précédemment. Il n’est pas toujours évident de le comprendre à la lecture et pourtant assez simple. Son comportement dépend de ce qu’il lui est appliqué. – il permet de convertir un block en proc :

defmethod&block block.call # Notre block est devenu un proc et nous pouvons l'appeler via la méthode callend
  • il permet de convertir un proc en block
  • si l’object qui lui est passé n’est ni un proc, ni un block il fera appel à to_proc sur l’objet, puis il convertira ce proc en block.

Conclusion

Voici un tableau récapitulatif des différences de ces fonctions :

FonctionBlockProcLambda
ClasseProcProcProc
Stockable en variableNonOuiOui
Interrompt l’exécution–OuiNon
Sensible aux nombres d’argumentsNonNonOui

À lire aussi

Diagnostiquer, comprendre et optimiser les performances d’une application React
4 mai 2026

Diagnostiquer, comprendre et optimiser les performances d’une application React

Lire la suite de l'article

Ouicommit Paris – IA : de l’expérimentation à l’industrialisation
15 avril 2026

Ouicommit Paris – IA : de l’expérimentation à l’industrialisation

Lire la suite de l'article

Ouidou et Scaleway : un partenariat stratégique pour accélérer le cloud souverain en Europe
8 avril 2026

Ouidou et Scaleway : un partenariat stratégique pour accélérer le cloud souverain en Europe

Lire la suite de l'article

Replay webinaire Ouidou x Sonar
2 juillet 2026

Replay webinaire Ouidou x Sonar

Lire la suite de l'article

Articles associés

Ouicommit Paris – IA : de l’expérimentation à l’industrialisation
15 avril 2026

Ouicommit Paris – IA : de l’expérimentation à l’industrialisation


Lire la suite
Ouidou et Scaleway : un partenariat stratégique pour accélérer le cloud souverain en Europe
8 avril 2026

Ouidou et Scaleway : un partenariat stratégique pour accélérer le cloud souverain en Europe


Lire la suite
Comment préparer votre Jira Cloud dès maintenant ? 
14 novembre 2025

Comment préparer votre Jira Cloud dès maintenant ? 


Lire la suite
Replay webinaire IA
5 novembre 2025

Replay webinaire IA


Lire la suite
  • Linkedin Ouidou
  • Youtube Ouidou

Blog Ouidou, le rendez-vous des équipes tech qui veulent comprendre avant de décider. Veille, retours d'expérience et décryptages pour rester à la pointe.

© 2026 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Découvrir Ouidou
    No results See all results