Implémentation du carnet d'adresses

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)
        1
        @personnes.push(personne)
    end
    def retire(personne)
        2
        @personnes.delete(personne)
    end
end

Explication du code:

1

La méthode Array#push permet d'ajouter un objet dans un tableau. L'objet sera empilé sur les objets existants, un peu comme si vous rajoutiez une assiette sur une pile d'assiettes.

2

La méthode Array#delete permet de supprimer un objet d'un tableau. Si le tableau contient plusieurs objets identiques, ils seront tous supprimés.

Pour mieux comprendre le fonctionnement de Array#delete, essayez ceci dans IRB:

>> a = [ 1, 3, 3, 3, 3, 5]  
=> [1, 3, 3, 3, 3, 5]
>> a.delete(3)
=> 3
>> a
=> [1, 5]

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.

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.

[Tip]Astuce

Il est possible de définir avec Ruby des blocs de code en utilisant deux syntaxes différentes:

  • @personnes.sort do |a, b|
        # ...
    end
    

  • @personnes.sort { |a, b|
        # ...
    }
    

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:

  • Utilisez la notation { ... } quand il est possible de faire tenir l'expression sur une seule ligne.

  • Sinon, utilisez do ... end.