Variables locales

Une variable est locale si son nom commence par une minuscule ou un blanc souligné (_). Les variables locales n’ont pas, contrairement aux variables d’instance ou globales, la valeur nil avant leur initialisation :

ruby> $foo
   nil
ruby> @foo
   nil
ruby> foo
ERR: (eval):1: undefined local variable or method `foo' for
main(Object)

La première affectation que l’on fait à une variable locale agit un peu comme une déclaration. Si vous vous référez à une variable locale non initialisée, l’interpréteur ruby croit à une tentative d’invoquer un méthode de ce nom, d’où le message d’erreur de l’exemple ci-dessus.

En général, la portée d’une variable locale est dans :

  • proc{ ... }
  • loop{ ... }
  • def … end
  • class … end
  • module … end
  • ... le programme entier si aucun des cas précédents ne s’est appliqué.

Dans l’exemple suivant, defined? est un opérateur qui vérifie si un identificateur est défini. Il rend une description de l’identificateur s’il est défini, et nil sinon. Comme vous voyez, la portée de bar est locale à la boucle ; et quand on quitte la boucle, bar devient indéfini.


 ruby> foo = 44; print foo, "\n"; defined? foo
 44
    "local-variable" 
 ruby> loop{bar=45; print bar, "\n"; break}; defined? bar
 45
    nil

Les objets procédures qui « vivent » dans la même portée partagent toutes les variables locales qui appartiennent aussi à cette portée. Ici la variable locale bar est partagée par main et par les objets procédures p1 et p2 :


 ruby> bar=0
    0
 ruby> p1 = proc{|n| bar=n}
    #<Proc:0x8deb0>
 ruby> p2 = proc{bar}
    #<Proc:0x8dce8>
 ruby> p1.call(5)
    5
 ruby> bar
    5
 ruby> p2.call
    5

Notez que le « bar=0 » du début ne saurait être omis : cette affectation a pour effet que la portée de bar comprendra p1 et p2. Sans elle p1 et p2 auraient chacune sa propre variable locale bar, et appeler p2 aurait produit une erreur “undefined local variable or method” (variable locale ou méthode non définie).

Une caractéristique puissante des objets procédures vient de leur capacité à être passés en arguments : les variables locales partagées restent valides même quand elles sont ainsi transmises hors de leur portée initiale.


 ruby> def boite
     |   contenu = 15
     |   get = proc{contenu}
     |   set = proc{|n| contenu = n}
     |   return get, set
     | end
    nil
 ruby> reader, writer = boite
    [#<Proc:0x40170fc0>, #<Proc:0x40170fac>] 
 ruby> reader.call
    15
 ruby> writer.call(2)
    2
 ruby> reader.call
    2

Ruby est fort sur les portées. Il est évident d’après notre exemple, que la variable contenu est partagée entre reader et writer. Mais nous pouvons aussi fabriquer de multiples paires reader-writer en utilisant boite comme elle est définie dans l’exemple ; chaque paire partage une variable locale contenu, et les paires n’interfèrent pas entre elles.


 ruby> reader_1, writer_1 = boite
    [#<Proc:0x40172820>, #<Proc:0x4017280c>]
 ruby> reader_2, writer_2 = boite
    [#<Proc:0x40172668>, #<Proc:0x40172654>]
 ruby> writer_1.call(99)
    99
 ruby> reader_1.call
    99
 ruby> reader_2.call
    15

Guide de l’utilisateur

Précédent : GDU : Variables d’instance Suivant : GDU : Constantes de classe