Retour au cours

la portée des variables : locale, instance et globale

Objectifs

  • Comprendre ce qu’est la “portée” (scope) d’une variable.
  • Distinguer les quatre types de variables en Ruby en fonction de leur préfixe : locale, d’instance (@), de classe (@@), et globale ($).
  • Savoir quel type de variable utiliser dans quel contexte.

La portée d’une variable détermine “qui” peut la voir et la modifier. C’est un concept clé pour éviter les bugs et écrire du code bien organisé.

1. Variable locale

C’est le type de variable que nous avons utilisé jusqu’à présent.

  • Syntaxe : Commence par une lettre minuscule ou un underscore. ma_variable = ...
  • Portée : Strictement limitée au bloc où elle est définie (une méthode, une boucle…). Une fois que le end du bloc est atteint, la variable est détruite.
def ma_methode
  variable_locale = "Je suis confinée ici."
  puts variable_locale
end

ma_methode # Affiche "Je suis confinée ici."

# puts variable_locale # -> Erreur ! undefined local variable or method

2. Variable d’instance (@)

Une variable d’instance est ce qui permet à un objet de conserver son propre état.

  • Syntaxe : Commence par un seul arobase (@). @nom_utilisateur = ...
  • Portée : Liée à une instance spécifique d’une classe. Elle est accessible par toutes les méthodes de cette même instance.
class Utilisateur
  def initialize(nom)
    # Chaque nouvel utilisateur aura son propre @nom
    @nom = nom
  end

  def saluer
    # Cette méthode peut accéder à @nom
    puts "Bonjour, je suis #{@nom}."
  end
end

alice = Utilisateur.new("Alice")
bob = Utilisateur.new("Bob")

alice.saluer # => "Bonjour, je suis Alice."
bob.saluer   # => "Bonjour, je suis Bob."

3. Variable de classe (@@)

Une variable de classe est partagée par toutes les instances d’une même classe. C’est assez rare, mais utile pour des propriétés qui concernent la classe dans son ensemble.

  • Syntaxe : Commence par deux arobases (@@). @@compteur = ...
  • Portée : Liée à la classe.
class Utilisateur
  @@nombre_utilisateurs = 0 # Partagée par tous

  def initialize(nom)
    @nom = nom
    @@nombre_utilisateurs += 1 # On incrémente la variable partagée
  end

  def self.compter # Une méthode de classe
    puts "Il y a #{@@nombre_utilisateurs} utilisateurs au total."
  end
end

Utilisateur.new("Alice")
Utilisateur.new("Bob")

Utilisateur.compter # => "Il y a 2 utilisateurs au total."

4. Variable globale ($)

Une variable globale est accessible depuis n’importe où dans votre programme.

  • Syntaxe : Commence par un dollar ($). $mode_debug = ...
$statut_global = "Démarrage"

def verifier_statut
  puts "Le statut actuel est : #{$statut_global}"
end

verifier_statut # => "Le statut actuel est : Démarrage"

C’est une très mauvaise pratique. L’utilisation de variables globales rend un programme imprévisible, car n’importe quelle partie du code peut modifier son état à tout moment, ce qui rend le débogage très difficile. Évitez-les à tout prix, sauf si vous avez une excellente raison.

Résumé

TypePréfixePortéeUsage typique
Localenom_variableBloc (méthode, boucle)Variable temporaire dans une méthode.
Instance@nom_variableInstance d’un objetStocker l’état d’un objet (le nom d’un utilisateur).
Classe@@nom_variableClasse et ses instancesPropriété partagée (un compteur).
Globale$nom_variableTout le programmeÀ éviter.

Exercices

  1. Portée locale :

    • Écrivez une méthode qui définit une variable locale.
    • Essayez d’accéder à cette variable en dehors de la méthode et observez l’erreur.
  2. Variables d’instance :

    • Créez une classe Voiture.
    • Dans la méthode initialize, initialisez deux variables d’instance : @marque et @couleur.
    • Créez une méthode description qui retourne une chaîne comme “Cette voiture est une [marque] de couleur [couleur].”
    • Créez deux instances de Voiture avec des marques différentes et appelez leur méthode description.
  3. (Théorique) Le danger des globales :

    • Imaginez un grand projet avec des dizaines de fichiers. Si une variable globale $config est utilisée, et qu’un bug étrange se produit où sa valeur change de manière inattendue, comment feriez-vous pour trouver quelle partie du code est responsable ? Expliquez pourquoi c’est si difficile.