Classes et méthodes

Nous sommes maintenant prêts pour créer notre propre classe Adresse. Commençons simplement par une classe qui ne contient que le champ "rue".

Voici un exemple:

1
class Adresse
    2
    def initialize(rue)
        3
        @rue = rue
    end
end

Explication:

1

Le mot clef class définit une classe. On associe une méthode à une classe simplement en définissant la méthode à l'intérieur de la classe.

2

La méthode initialize permet de construire la classe. Il s'agit en fait du constructeur de la classe. Chaque classe doit contenir une méthode initialize!

3

@rue est une variable de classe. Ça ressemble un peu à une clef de hachage. Le symbole @ permet de distinguer les variables d'un objet. Chaque fois que vous allez instancier un objet de la classe Adresse, cet objet contiendra une variable @rue.

Utilisons maintenant cette classe pour créer un objet:

adresse = Adresse.new("Rue de la Renaissance, 49")

Et voila le travail. adresse est dès à présent un objet provenant de la classe Adresse.

Comment s'y prendre pour obtenir la rue de notre objet adresse? Nous pouvons par exemple écrire une méthode qui renvoie les données:

class Adresse
    def initialize(rue)
        @rue = rue
    end
    
    # Renvoie simplement @rue
    def rue 
        @rue
    end
end

Maintenant, la méthode Adresse#rue vous permet d'obtenir la rue d'une adresse. Dans IRB:

>> adresse.rue
=> "Rue de la Renaissance, 49"

Une propriété d'un objet, visible de l'extérieur, est appelée attribut. Dans ce cas, rue est un attribut. Plus spécialement, un attribut en lecture, car il permet de lire la valeur d'une des propriétés de la classe.

Comme ce genre d'attribut se retrouve assez souvent, Ruby nous offre un raccourci: le mot clef attr_reader:

class Adresse
    attr_reader :rue
    def initialize(rue)
        @rue = rue
    end
end    

Évidemment, il est également possible de modifier une propriété d'un objet. Par exemple, en rajoutant une méthode dans la classe:

class Adresse
    attr_reader :rue
    def initialize(rue)
        @rue = rue
    end
    def rue=(une_rue)
        @rue = une_rue
    end
end    

Et voici comment utiliser cette nouvelle méthode:

adresse.rue = "Une autre adresse"

[Note]Note

Remarquez que Ruby accepte des espaces entre rue et = (dans l'affectation). Par contre, il ne faut pas mettre d'espaces dans la définition de la méthode.

Maintenant que nous savons comment modifier les données de notre classe, nous n'avons plus besoin d'initialiser la rue dans le constructeur. Nous pouvons donc simplifier la méthode initialize:

class Adresse
    attr_reader :rue
    def initialize
        @rue = "" 
    end
    def rue=(une_rue)
        @rue = une_rue
    end
end    

adresse = Adresse.new
adresse.rue = "Rue de la Renaissance, 49" 

Cette petite modification rendra le code plus simple par la suite, lorsque nous rajouterons les autres données (le code postal, la ville, le pays).

Maintenant, rue est également un attribut en écriture, car via la méthode Adresse#rue=, il nous est possible de modifier sa valeur. Comme pour la lecture, il s'agit d'une opération courante, et Ruby nous permet d'utiliser le mot clef attr_writer:

class Adresse
    attr_reader :rue
    attr_writer :rue
    def initialize
        @rue = "" 
    end
end    

Fort souvent, vous aurez besoin d'attributs qui fonctionneront à la fois en lecture et en écriture. Comme vous vous en doutez peut-être, Ruby possède un mot clef qui regroupe ces deux états à la fois: attr_accessor:

class Adresse
    attr_accessor :rue
    def initialize
        @rue = "" 
    end
end    

Il est maintenant temps de définir entièrement la structure adresse de notre carnet sous la forme d'une classe. Le code ci-dessous ne devrait pas vous poser de problème:

class Adresse
    attr_accessor :rue, :code_postal, :ville, :pays
    def initialize
        @rue = @code_postal = @ville = @pays = ""
    end
end

[Note]Note

Notez que attr_accessor accepte plusieurs arguments.