
Comment séparer son code en plusieurs fichiers (`require_relative`)
Apprenez à structurer vos projets Ruby en séparant le code en plusieurs fichiers avec `require_relative`. Découvrez pourquoi c'est une pratique essentielle pour la lisibilité, la maintenance et la collaboration.
Pourquoi est-il essentiel de diviser son code ?
Lorsque vous débutez, il est naturel de tout écrire dans un seul et même fichier. Pour un script de quelques dizaines de lignes, c'est parfaitement acceptable. Cependant, dès que votre application grandit, cette approche montre ses limites et devient contre-productive. Le fichier devient long, difficile à lire, et retrouver une méthode spécifique se transforme en une véritable chasse au trésor.
La solution est la modularité : diviser votre code en plusieurs fichiers, chacun ayant une responsabilité unique. Par exemple, une classe User ira dans un fichier user.rb, une classe Product dans product.rb, etc. Cette pratique, appelée "séparation des préoccupations" (Separation of Concerns), rend votre code plus facile à comprendre, à maintenir et à déboguer. C'est également la clé pour pouvoir réutiliser des composants et collaborer efficacement en équipe.
En Ruby, le principal outil pour connecter ces fichiers entre eux est la commande require_relative. Elle permet à un fichier de charger le contenu d'un autre fichier, rendant ses classes et méthodes disponibles.
Le mécanisme de `require_relative` expliqué
La commande require_relative est une instruction qui dit à l'interpréteur Ruby : "Arrête-toi un instant, va chercher le fichier que je t'indique, exécute-le, puis reviens ici pour continuer". Le mot-clé important est "relative". Cela signifie que le chemin que vous fournissez est calculé par rapport à l'emplacement du fichier actuel.
Imaginons la structure de fichiers suivante, où deux fichiers se trouvent dans le même répertoire :
mon_projet/
├── main.rb
└── greeter.rbLe fichier greeter.rb contient une méthode simple :
# greeter.rb
def say_hello(name)
puts "Hello, #{name}!"
endDans main.rb, pour pouvoir utiliser la méthode say_hello, nous devons d'abord charger le fichier greeter.rb. C'est ici que require_relative intervient.
# main.rb
# On charge le fichier greeter.rb qui est dans le même dossier.
require_relative 'greeter'
# Maintenant, la méthode say_hello est disponible !
say_hello('Alice')
#=> Affiche "Hello, Alice!"Conseil pro : Vous remarquerez que nous n'avons pas besoin de spécifier l'extension .rb. C'est une convention en Ruby ; l'interpréteur est assez intelligent pour la deviner.
Cas pratique : organiser un projet avec un sous-dossier
Dans un projet réel, il est courant de regrouper les fichiers contenant la logique principale (comme les classes) dans un sous-dossier, souvent nommé lib (pour "library"). Le fichier principal, ou point d'entrée de l'application, reste à la racine.
Considérons cette structure plus professionnelle :
mon_projet/
├── lib/
│ └── user.rb
└── app.rbLe fichier lib/user.rb définit notre classe User.
# lib/user.rb
class User
attr_reader :name
def initialize(name)
@name = name
end
endDepuis app.rb, nous devons indiquer le chemin relatif vers user.rb. Comme user.rb est dans le dossier lib, le chemin sera 'lib/user'.
# app.rb
# On charge le fichier user.rb en spécifiant le chemin depuis app.rb
require_relative 'lib/user'
# La classe User est maintenant définie et nous pouvons l'utiliser
user = User.new('Bob')
puts user.name
#=> Affiche "Bob"Cette organisation est la base de la quasi-totalité des projets Ruby. Elle sépare clairement le code exécutable (app.rb) du code de la bibliothèque (tout ce qui est dans lib/).
Erreur commune : `LoadError` et chemin incorrect
L'erreur la plus fréquente avec require_relative est la LoadError. Ce message d'erreur signifie simplement que Ruby n'a pas trouvé le fichier à l'emplacement que vous avez spécifié.
cannot load such file -- /chemin/vers/votre/projet/user (LoadError)Cette erreur se produit presque toujours pour une des deux raisons suivantes :
- Une faute de frappe dans le nom du fichier ou du dossier (par exemple,
'lib/users'au lieu de'lib/user'). - Une mauvaise compréhension du chemin relatif. Rappelez-vous toujours : le chemin part de l'endroit où se trouve le fichier contenant l'instruction
require_relative. Si vous déplacez un fichier, vous devrez probablement mettre à jour ses chemins d'accès.
Une autre erreur courante est d'oublier complètement l'instruction require_relative. Dans ce cas, Ruby vous dira qu'il ne connaît pas la classe ou la méthode que vous essayez d'utiliser (par exemple, uninitialized constant User), car le fichier qui la définit n'a jamais été chargé.
Un pas vers la gestion des dépendances
Maîtriser require_relative est la première étape pour comprendre la gestion des dépendances. Pour l'instant, nous gérons des dépendances internes : nos propres fichiers qui dépendent les uns des autres.
Dans la section suivante, nous allons étendre ce concept aux dépendances externes avec Bundler et les gems. Le principe reste le même : rendre du code externe disponible dans notre projet. La connaissance que vous venez d'acquérir sur le chargement de fichiers est donc le socle sur lequel nous allons construire une gestion de projet encore plus puissante et professionnelle.