Photo de Jack Anstey sur Unsplash

An aperçu du contexte d’exécution des blocs

Mehdi Farsi

Follow

Sep 20, 2019 – 3 min lu

Dans cet article, nous allons explorer les sujets suivants :

  • scopes et blocs
  • garde de scope plat en classe/module

D’abord, n’hésitez pas à parcourir les portes de scope en Ruby : Partie II article.

Avant de commencer

Je suis ravi de partager avec vous notre dernier projet : Fun Facts about Ruby – Volume 1

N’hésitez pas à faire passer le mot et à partager ce lien ! 🙏

Merci pour votre temps!

En Ruby, un bloc peut accéder à la portée extérieure

Dans cet exemple, nous pouvons accéder à la variable outer_scope_variable à l’intérieur de notre bloc. Notre bloc a accès à cette variable même si la variable est déclarée à une portée de niveau main. Dans ce cas, on dit que le bloc aplatit les scopes. C’est pourquoi nous appelons communément ce mécanisme : Flat Scope.

D’autre part, le bloc crée une portée isolée – même si la valeur de self à l’intérieur du bloc reste l’objet main.

On ne peut donc pas accéder aux variables locales définies à l’intérieur du bloc

Ici, nous ne pouvons pas accéder au block_variable depuis la portée extérieure. Maintenant que nous sommes plus familiers avec la notion de flat scope en Ruby, voyons si cette notion a un impact sur la définition des classes.

Classe, module et bloc

En Ruby, ce que vous appelez communément une classe est, derrière la scène, une instance de la classe Class

Ici, nous créons les classes Hello et Greeting de deux manières différentes :

  • en utilisant le mot-clé class
  • en assignant une instance de la classe Class à la constante Greeting

Notez que nous passons un bloc à la méthode Class.new. Ce bloc sera interprété comme le contenu de la classe. Normalement, une classe ne peut pas accéder aux variables définies dans la portée externe – car le mot clé class change la valeur de self et crée une portée isolée.

Donc, comme nous utilisons un bloc pour créer notre classe Greeting alors nous devrions pouvoir utiliser le mécanisme de portée plate. Vraiment ?

On voit ici que la valeur de self change lorsqu’on utilise class ou Class.new.

De plus, notre bloc Class#message est toujours isolé de l’objet main grâce à l’utilisation du mot clé def. En effet, comme notre bloc est exécuté dans le contexte de la méthode alors le bloc aplatit la portée au sein de cet objet donné – et non pas avec une portée plus élevée comme l’objet main.

C’est pourquoi nous n’avons pas accès à outer_variable au sein de message.

Mais si nous utilisons define_method pour définir message alors la portée est aplatie

Ici, comme define_method(:message) prend un bloc comme argument, la portée de ce bloc est aplatie et cette méthode a accès à outer_variable.

Voilà!

Articles

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.