
Comment utiliser la gem `debug` pour du débogage pas à pas
Apprenez à maîtriser le débogage pas à pas en Ruby avec la gem `debug`. Ce tutoriel vous montre comment poser des points d'arrêt, inspecter les variables et naviguer dans votre code pour trouver et corriger les bugs plus rapidement.
Pourquoi un simple `puts` ne suffit-il pas toujours ?
Au début de votre apprentissage, l'utilisation de puts (ou p pour une inspection plus détaillée) pour afficher le contenu d'une variable à un instant T est une technique de débogage rapide et efficace. Elle est parfaite pour des scripts simples. Cependant, dès que la logique se complexifie, cette méthode montre ses limites.
Imaginez que vous deviez inspecter une variable à l'intérieur d'une boucle qui s'exécute des centaines de fois, ou comprendre pourquoi une série d'appels de méthodes imbriquées ne produit pas le résultat attendu. Inonder votre console de puts devient vite contre-productif. C'est là qu'un véritable débogueur intervient.
Pensez à un débogueur comme à un microscope pour votre code. Il vous permet de mettre l'exécution de votre programme en pause à un endroit précis, d'inspecter l'état de toutes les variables à ce moment-là, et d'exécuter votre code ligne par ligne. La gem debug est l'outil standard et moderne intégré à Ruby pour accomplir cette tâche.
Comment installer et intégrer la gem `debug` dans un projet ?
Depuis Ruby 3.1, la gem debug est incluse par défaut. Cependant, pour assurer la cohérence et la portabilité de votre projet, il est considéré comme une bonne pratique de l'ajouter explicitement à votre Gemfile. Cela garantit que tout autre développeur travaillant sur le projet utilisera la même version de l'outil.
Ouvrez votre Gemfile et ajoutez la ligne suivante, généralement dans le groupe de développement :
group :development, :test do
gem 'debug', '>= 1.0'
endEnsuite, exécutez la commande bundle install dans votre terminal pour l'installer. Une fois installée, pour l'activer dans un script spécifique, il vous suffit d'ajouter la ligne require 'debug' au tout début de votre fichier. C'est cette ligne qui rend les fonctionnalités du débogueur, comme les points d'arrêt, disponibles dans votre code.
Comment poser un point d'arrêt pour pauser l'exécution ?
Le concept central du débogage pas à pas est le point d'arrêt (ou breakpoint). C'est une instruction que vous placez dans votre code pour dire à Ruby : "Quand tu arriveras à cette ligne, arrête tout et attends mes instructions".
Pour poser un point d'arrêt avec la gem debug, vous insérez simplement la ligne binding.break (ou son alias plus court, debugger) à l'endroit où vous souhaitez que la pause se produise.
Prenons un exemple simple. Imaginons une méthode qui calcule une somme, et nous voulons inspecter les variables juste avant que le résultat ne soit retourné.
require 'debug'
def add(a, b)
result = a + b
# Point d'arrêt ici !
binding.break
result
end
add(5, 10)Lorsque vous exécutez ce fichier (par exemple avec ruby mon_fichier.rb), l'exécution se figera juste après le calcul de result. Votre terminal affichera alors une invite de commande spéciale, souvent (rdbg), signalant que la session de débogage est active et attend vos commandes.
Quelles sont les commandes essentielles pour naviguer dans la session de débogage ?
Une fois dans la session (rdbg), vous disposez de plusieurs commandes pour contrôler le flux d'exécution et inspecter l'état du programme. Voici les plus importantes à connaître :
- Inspecter une variable : Tapez simplement le nom de la variable (par ex.
result) et appuyez sur Entrée. Le débogueur affichera sa valeur actuelle. c(oucontinue) : Reprend l'exécution normale du programme jusqu'au prochain point d'arrêt ou jusqu'à la fin du script.n(ounext) : Exécute la ligne de code actuelle et s'arrête à la ligne suivante. Si la ligne actuelle est un appel de méthode, cette commande exécute la méthode entière sans y entrer.s(oustep) : Exécute la ligne de code actuelle. Si c'est un appel de méthode, le débogueur pénètre à l'intérieur de cette méthode et s'arrête à sa première ligne. C'est la différence clé avecnext.q(ouquit) : Termine immédiatement la session de débogage et le script.
Conseil de pro : La console de débogage est un REPL (comme IRB) à part entière. Vous pouvez non seulement afficher des variables, mais aussi exécuter n'importe quel code Ruby dans le contexte actuel. Par exemple, vous pourriez taper a * 100 pour voir ce que vaudrait ce calcul, ou même modifier la valeur d'une variable en direct avec result = 999.
Mise en pratique : trouver un bug dans une boucle
Imaginons une fonction qui doit doubler chaque nombre d'un tableau, mais qui contient une erreur subtile.
require 'debug'
def double_numbers(numbers)
doubled = []
numbers.each do |number|
# Mettons un point d'arrêt pour voir ce qui se passe à chaque tour.
binding.break
doubled << number * 2
number = 0 # Bug : on modifie la variable par erreur
end
doubled
end
double_numbers([1, 2, 3])En exécutant ce code, la session de débogage s'ouvre au premier tour de boucle. Vous pouvez taper number pour voir sa valeur (1), puis doubled ([]). Tapez n pour avancer. Maintenant, si vous inspectez à nouveau number, vous verrez qu'il est devenu 0 à cause de la ligne de code erronée. Le débogueur vous a permis de voir l'état changer pas à pas et d'identifier la cause exacte du problème. Sans lui, vous auriez simplement vu un résultat final incorrect sans comprendre le processus qui y a mené.