Contenu

Sphères de visibilité, comme les pièces d’une maison

Lorsque nous avons parlé de variables, nous avons mentionné que le type de variables le plus courant est la « variable locale », sans expliquer davantage pourquoi elles sont locales. Local à quoi? Où? Nous sommes enfin prêts à l’expliquer davantage.

Puisque nous avons maintenant parlé de méthodes, nous pouvons également discuter d’un autre concept important: les étendues.

Wikipedia dit: « En programmation, la portée d’un nom est la partie d’un programmeoù le nom est valide: où le nom peut être utilisé pour faire référence à quelque chose. » (légèrement modifié pour correspondre à notre propre terminologie)

Les noms sont connus (ou définis) dans une certaine portée, et inconnus (ou non définis) en dehors de cette portée.

Vous pouvez penser à une portée comme à une sphère, une bulle ou une pièce (avec nowindows et portes fermées): Certains noms, comme les noms de variables, sont « connus » et « visibles » à l’intérieur de la pièce. D’autres noms, connus et visibles dans une autre pièce ne sont pas connus dans cette pièce, mais seulement dans l’autre pièce.

Chaque fois qu’il y a un appel de méthode et que le flux d’exécution entre dans le corps de themethod, il entre dans une nouvelle portée, ou « pièce ». Les choses qui sont « locales » dans la portée de cette méthode (c’est-à-dire les choses qui sont « à l’intérieur » de la pièce), ne sont que visibles dans cette portée. En dehors de cela, ils sont inconnus.

Variable ou méthode locale non définie

C’est également une bonne occasion de parler d’un message d’erreur que vous voyez le plus souvent. Par exemple, vous le verrez à chaque fois que vous avez fait une faute de frappe et que vous avez mal orthographié un nom de variable ou de méthode.

Considérez ce code:

def add_two(number) number + 2endputs add_two(3)puts number

La ligne puts add_two(2) affichera 5, mais la ligne puts number déclenchera ensuite une erreur.

Ceci est dû au fait que la variable number à laquelle est attribué le numéro 3 lorsque nous appelons la méthode est une variable locale. Il est local à la portée de la méthode. Il est créé lorsque le flux d’exécution entre dans la méthode.

En dehors de cette portée, lorsque le flux d’exécution est revenu de la méthodela portée de la méthode a été détruite et toutes les variables locales ont disparu. La variable locale number n’est donc pas connue, et Ruby déclenche une erreur disant undefined local variable or method 'number'.

Si vous pensez un peu à ce message d’erreur, cela a-t-il du sens ?

Nous avons ignoré silencieusement le fait que, dans Ruby, les noms de variables locaux et les noms de méthodes sont écrits de la même manière: ce ne sont que des mots simples.Par exemple, ici :

number = 2puts number

number est une variable locale, et elle est utilisée dans la ligne puts number.

Cependant, ici:

def number 2endputs number

number est le nom d’une méthode. Et il peut être utilisé (appelé) de la même manière exacte: puts number

C’est parce que Ruby, lorsqu’il exécute un programme, évalue une instruction après une autre. Et lorsqu’il rencontre un mot simple comme number, il vérifiera d’abord si, dans la portée actuelle, il connaît une variable locale avec le même nom. Si c’est le cas, il utilisera la valeur associée à cette variable. S’il n’y a pas de variable locale avec ce nom, elle cherchera une méthode. S’il n’y a pas non plus de méthode avec ce nom, le message d’erreur undefined local variable or method 'number' sera alors déclenché.

Le message d’erreur est donc assez précis, mais semble aussi un peu compliqué. Ce qu’il essaie fondamentalement de dire est:

Vous avez utilisé le mot « nombre » ici, et je ne le sais pas (dans cette portée). Vouliez-vous utiliser une variable locale ? Ou une méthode?

Cela a-t-il du sens ?

Retour au sujet des étendues locales. Regardons un autre exemple:

number = 1def add_to(number) number + 2endputs add_to(3)

Que pensez-vous que la sortie sera? Est-ce que ce sera 3, ou 5? Autre chose ?

Si vous exécutez le code, vous verrez qu’il s’agit de 5.

La raison en est que nous attribuons le numéro 1 dans la portée externe à avariable number, mais cette variable n’est alors jamais utilisée: la seule autre ligne dans la portée externe est la dernière ligne puts add_to(3), et cette ligne n’utilise pas la variablenumber.

Au lieu de cela, lorsque le flux de contrôle entre dans la méthode add_toRuby créera une nouvelle portée locale, et définira une nouvelle variable locale number qui est attribué au nombre 3 qui a été passé à la méthode. Cette nouvelle variable number est locale à la portée de la méthode, et c’est donc une variable différente de celle de la toute première ligne, dans la portée externe.

Nous avons trouvé ce qui suit une bonne métaphore pour les portées:

Lorsque Ruby entre dans une méthode, c’est comme si elle entrait dans une nouvelle pièce brillante dans une maison. Avec elle, elle apporte les objets qui sont passés comme arguments à l’appel de la méthode. Dans l’exemple ci-dessus, elle apporte un objet qui est le nombre 3.

Maintenant, dès que Ruby entre dans la méthode, elle colle des notes post-it sur theobjects, selon la liste d’arguments de la définition de la méthode. Dans notre exemple, c’est le nom number. Donc, à partir de maintenant, dans cette pièce, il y a une variable locale connue qui a une valeur assignée: L’objet (numéro) 3 avec la note post-it number dessus.

Dans notre exemple, la portée extérieure et la portée de la méthode add_two, sontdeux pièces différentes, et il y a deux notes post-it différentes collées surdeux numéros différents, qui ont juste le même nom dessus.

Laisser un commentaire

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