Maintenant que nous avons les classes Adresse et Personne, il ne nous reste plus qu'à créer la classe Carnet.
Notre carnet d'adresse doit contenir un tableau, qui contient tous nos contacts. Nous n'utiliserons pas attr_accessor parce que nous ne voulons pas qu'on puisse accéder directement au tableau. Nous allons donc écrire nos propres méthodes pour travailler sur le tableau interne.
Voici à quoi peut ressembler le code de notre classe Carnet:
class Carnet def initialize # Initialise le tableau. Meme chose que ``Array.new''. @personnes = [] end end
C'était plutot facile. Rajoutons maintenant deux méthodes d'accès: Carnet#ajoute et Carnet#retire:
class Carnet def initialize @personnes = [] end def ajoute(personne) @personnes.push(personne) end def retire(personne) @personnes.delete(personne) end end
Explication du code:
Nous allons maintenant rajouter une super fonctionnalité dans notre Carnet: un tri automatique. Par exemple, imaginez le code suivant:
carnet = Carnet.new carnet.ajoute nicolas carnet.ajoute francois carnet.ajoute marina
Le carnet classera automatiquement les personnes à chaque ajout. Cette fonctionnalité va rendre notre classe Carnet bien plus intéressante qu'un simple tableau.
Nous voulons que le tableau contenant les contacts soit trié par ordre alphabétique, en se basant sur le nom complet de la personne (prénom et nom de famille). Dans la section précédente, nous avons écrit ceci:
# ``carnet'' est un tableau ici carnet.sort do |personne_a, personne_b| personne_a["prénom"] <=> personne_b["prénom"] end
Adaptons ce code pour notre classe Carnet:
@personnes.sort do |a, b| a.prenom <=> b.prenom end
Si vous avez effectué les exercices du chapitre précédent, vous devriez déjà savoir comment trier les personnes en se basant sur leur nom complet. Voici une façon de le faire:
@personnes.sort do |a, b| if a.prenom == b.prenom a.nom <=> b.nom else a.prenom <=> b.prenom end end
Si les prénoms sont les mêmes, nous comparons les noms de famille. Sinon, on compare les prénoms.
Le principe fondamental de la simplification est de diviser le problème en petites parties. Nous pouvons déplacer le bloc de code dans une méthode:
def par_nom(a, b) if a.prenom == b.prenom a.nom <=> b.nom else a.prenom <=> b.prenom end end
Maintenant, nous pouvons écrire:
@personnes.sort do |a, b| par_nom(a, b) end
Ce qui est beaucoup plus simple à lire.
Astuce | |
---|---|
Il est possible de définir avec Ruby des blocs de code en utilisant deux syntaxes différentes:
Ces deux notations veulent dire exactement la même chose. La différence est que do ... end est plus lisible, et que { ... } est plus court. Nous pouvons écrire le tri de notre tableau de cette façon: @personnes.sort { |a, b| par_nom(a, b) } Vous pouvez litéralement lire «tri de personnes par le nom». C'est du code très lisible. Voici une suggestion:
|
Il est maintenant temps de déplacer ce code dans notre classe Carnet, et d'implémenter notre tri automatique:
class Carnet def initialize @personnes = [] end def ajoute(personne) @personnes.push(personne) @personnes = @personnes.sort { |a, b| par_nom(a, b) } end def retire(personne) @personnes.delete(personne) end def par_nom(a, b) if a.prenom == b.prenom a.nom <=> b.nom else a.prenom <=> b.prenom end end end
Maintenant, à chaque fois que vous ajouterez une personne dans le carnet, ce dernier sera trié automatiquement!