Accesseurs

Qu’est-ce qu’un accesseur ?

Nous avons brièvement discuté les variables d’instance dans un chapitre précédent, mais nous n’en avons pas fait grand-chose jusqu’à maintenant. Les variables d’instance d’un objet sont ses attributs, les choses qui le distinguent des autres objets de la même classe. Il est important d’être capable de lire et d’écrire ces attributs, et nous avons besoin pour ce faire de méthodes appelées accesseurs d’attributs. Nous verrons dans un moment que nous n’avons pas toujours à écrire ces méthodes explicitement, mais voyons le reste du film d’abord. Les deux sortes d’accesseurs sont les writers (« écriveurs ») et les readers (lecteurs).


ruby> class Fruit
   |   def set_kind(k)  # un écriveur
   |     @kind = k
   |   end
   |   def get_kind     # un lecteur
   |     @kind
   |   end
   | end
  nil
ruby> f1 = Fruit.new
  #<Fruit:0xfd7e7c8c>
ruby> f1.set_kind("peach")  # utilise l'écriveur
  "peach" 
ruby> f1.get_kind           # utilise le lecteur
  "peach" 
ruby> f1                    # inspecte l'objet
  #<Fruit:0xfd7e7c8c @kind="peach">

C’est simple : nous pouvons stocker et récupérer l’information sur la sorte de fruits que nous manipulons. Mais nos noms de méthode sont un peu verbeux. Ce qui suit est plus bref, et plus conventionnel en ruby :


ruby> class Fruit
   |   def kind=(k)
   |     @kind = k
   |   end
   |   def kind
   |     @kind
   |   end
   | end
  nil
ruby> f2 = Fruit.new
  #<Fruit:0xfd7e7c8c>
ruby> f2.kind = "banane" 
  "banane" 
ruby> f2.kind
  "banane" 

La méthode inspect

Il faut faire ici une petite digression. Vous aurez remarqué maintenant que lorsque nous essayons de regarder un objet directement, on nous montre un truc abscons du genre #. Ceci est simplement le comportement par défaut, et nous sommes libres de le changer. Tout ce dont nous avons besoin est d’ajouter une méthode nommée inspect. Elle doit retourner une chaîne qui décrit l’objet d’une façon qui nous plaise mieux, par exemple en donnant la valeur de tout ou partie de ses variables d’instance.


ruby> class Fruit
   |   def inspect
   |     "Un fruit de la variété " + @kind 
   |   end
   | end
  nil
ruby> f2
  "Un fruit de la variété banane" 

Une méthode proche est to_s (convertir en chaîne), qui est utilisée quand on imprime un objet. En général, vous pouvez penser à inspect comme à un outil qui sert quand on écrit et débogue un programme, et à to_s comme un moyen de raffiner les sorties d’un programme. eval.rb utilise inspect pour tous ses affichages. Vous pouvez utiliser la méthode p pour obtenir facilement des affichages d’aide à la mise au point dans vos programmes.


# Ces deux lignes sont équivalentes:
p anObject
print anObject.inspect, "\n" 

Faire facilement ses accesseurs

Du fait qu’on a constamment besoin d’accesseurs pour ses variables d’instance, ruby fournit des raccourcis plus commodes que les formes standards.

Raccourci Equivaut à
attr_reader :v def v; @v; end
attr_writer :v def v=(value); @v=value; end
attr_accessor :v attr_reader :v; attr_writer :v
attr_accessor :v, :w attr_accessor :v; attr_accessor :w

Tirons parti de cela et ajoutons un indicateur de fraîcheur à nos fruits. D’abord nous générons automatiquement un accesseur en lecture et en écriture, puis nous incorporons la nouvelle information dans inspect :


ruby> class Fruit
   |   attr_accessor :condition
   |   def inspect
   |     "Une " + @kind + @condition" 
   |   end
   | end
  nil
ruby> f2.condition = "mûre" 
  "mûre" 
ruby> f2
  "Une banane mûre" 

h2. On continue avec nos fruits

Si personne ne mange nos fruits mûrs, nous pourrions peut-être laisser le temps prélever son tribut.


ruby> class Fruit
   |   def le_temps_passe
   |     @condition = "pourrie" 
   |   end
   | end
  nil
ruby> f2
  "Une banane mûre" 
ruby> f2.le_temps_passe
  "pourrie" 
ruby> f2
  "Une banane pourrie" 

Mais en jouant comme cela, nous avons introduit un petit problème. Que se passe-t-il si nous essayons de créer maintenant un troisième fruit ? Souvenez-vous que les variables d’instance n’existent pas tant qu’on ne leur a pas assigné une valeur…


ruby> f3 = Fruit.new
ERR: failed to convert nil into String

C’est la méthode inspect qui se plaint ici, et à bon droit. Nous lui avons demandé de rendre compte de la sorte (kind) et de l’état (condition) d’un fruit, mais pour l’instant, f3 n’a reçu aucun attribut. Si nous voulions, nous pourrions réécrire la méthode inspect pour qu’elle teste les variables d’instance en utilisant la méthode defined? et ne rende compte d’elles que si elles existent, mais ça n’est peut-être pas très utile, vu que tout fruit réel a une variété et un état, et que nous devrions plutôt faire en sorte que ces attributs soient toujours valorisés d’une façon ou d’une autre. C’est le sujet du prochain chapitre.

Guide de l’utilisateur

Précédent : GDU : Gestion des exceptions : ensure Suivant : GDU : Initialisation des objets