Comment puis-je déboguer les scripts Ruby?



debugging (12)

J'ai copié le code Ruby suivant sur Internet et apporté quelques modifications.

#insert code here

Mais ça ne marche pas!

S'il vous plaît aider. Que puis-je faire pour déboguer le programme par moi-même?

https://ffff65535.com


  1. Vous pouvez imprimer vos variables en cours de route
  2. Activer le drapeau -w (avertissements)
  3. Utilisez un outil tel que ruby-debug

  1. En Ruby:

    ruby -rdebug myscript.rb 
    

    puis,

    • b <line> : mettre le point de rupture
    • et n(ext) ou s(tep) et c(ontinue)
    • p(uts) pour l'affichage

    (comme le débogage perl)

  2. Dans Rails: lancez le serveur avec

    script/server --debugger
    

    et ajoutez le debugger dans le code.


Comme rampe recommandée: utilisez pry! Je ne peux qu'être d'accord là-dessus.

pry est un bien meilleur résultat que irb.

Vous devez ajouter

require 'pry'

à votre fichier source, puis insérez un point d'arrêt dans votre code source en ajoutant

binding.pry

à l'endroit où vous voulez voir les choses (c'est comme déclencher un point d'arrêt dans un environnement IDE classique)

Une fois que votre programme a atteint le

binding.pry

En ligne, vous serez jeté dans le repli de Pry, avec tout le contexte de votre programme à portée de main, de sorte que vous pouvez simplement explorer tout autour, étudier tous les objets, changer d'état, et même changer de code à la volée.

Je crois que vous ne pouvez pas changer le code de la méthode dans laquelle vous êtes actuellement, donc vous ne pouvez malheureusement pas changer la ligne suivante à exécuter. Mais bon code ruby ​​tend à être une seule ligne de toute façon ;-)


Depuis Ruby 2.4.0, il est plus facile de démarrer une session IRB REPL au milieu d'un programme Ruby. Placez ces lignes au point du programme que vous voulez déboguer:

require 'irb'
binding.irb

Vous pouvez exécuter du code Ruby et imprimer des variables locales. Tapez Ctrl + D ou quit pour terminer le REPL et laissez le programme Ruby continuer à fonctionner.

Vous pouvez également utiliser puts et p pour imprimer les valeurs de votre programme lorsqu'il est en cours d'exécution.


Il y a beaucoup de débogueurs avec des fonctionnalités différentes, sur la base desquelles vous faites un choix. Mes priorités étaient satisfaites des pry-moves qui étaient:

  • informations rapidement compréhensibles sur la façon d'utiliser
  • étapes intuitives (comme un pas facile dans les blocs)
  • "reculer" (les pry-moves satisfont partiellement le besoin)

Je recommande fortement cette vidéo, afin de choisir l'outil approprié pour déboguer notre code.

https://www.youtube.com/watch?v=GwgF8GcynV0

Personnellement, je soulignerais deux grands sujets dans cette vidéo.

  • Pry est génial pour les données de débogage, "pry est un explorateur de données" (sic)
  • Débogueur semble être préférable de déboguer étape par étape.

C'est mes deux cents!


La mère de tous les débogueurs est un ancien écran d'impression. La plupart du temps, vous ne voulez probablement inspecter que des objets simples, un moyen rapide et facile est comme ceci:

@result = fetch_result

p "--------------------------"
p @result

Ceci affichera le contenu de @result sur STDOUT avec une ligne devant pour faciliter l'identification.

Bonus si vous utilisez un framework de chargement automatique / rechargement comme Rails, vous n'aurez même pas besoin de redémarrer votre application. (Sauf si le code que vous déboguez n'est pas rechargé en raison de paramètres spécifiques au framework)

Je trouve que cela fonctionne pour 90% du cas d'utilisation pour moi. Vous pouvez également utiliser ruby-debug, mais je trouve que c'est excessif la plupart du temps.


Pour facilement déboguer le script shell Ruby, changez simplement sa première ligne de:

#!/usr/bin/env ruby

à:

#!/usr/bin/env ruby -rdebug

Ensuite, à chaque fois que la console du débogueur est affichée, vous pouvez choisir:

  • c pour continuer (à l'exception suivante, point d'arrêt ou ligne avec: debugger ),
  • n pour la ligne Next,
  • w / where afficher la pile frame / call,
  • l Afficher le code actuel,
  • cat pour montrer les catchpoints.
  • h pour plus d'aide.

Voir aussi: ruby-debug , raccourcis clavier pour ruby-debug gem .

Au cas où le script se hangs et que vous avez besoin d'un backtrace, essayez d'utiliser lldb / gdb comme lldb :

echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)

puis vérifiez votre processus au premier plan.

Remplacez lldb par gdb si cela fonctionne mieux. Préfixe avec sudo pour déboguer le processus non-propriétaire.


Toutes les autres réponses donnent déjà presque tout ... Juste un petit plus.

Si vous voulez un peu plus de débogueur IDE (non-CLI) et que vous n'avez pas peur d'utiliser Vim comme éditeur, je vous suggère le plugin Vim Ruby Debugger .

Sa documentation est assez simple, alors suivez le lien et voyez. En bref, il vous permet de définir le point d'arrêt à la ligne en cours dans l'éditeur, voir les variables locales dans la fenêtre astucieuse sur pause, pas sur / dans - presque toutes les fonctionnalités habituelles du débogueur.

Pour moi, il était assez agréable d'utiliser ce débogueur vim pour déboguer une application Rails, bien que les riches fonctionnalités de Rails en éliminent presque tout le besoin.


Utilisez Pry ( GitHub ).

Installer via:

$ gem install pry
$ pry

Puis ajouter:

require 'pry'

dans votre programme.


supprime toutes les choses

Bienvenue à 2017 ^ _ ^

D'accord, donc si vous n'êtes pas opposé à essayer un nouvel IDE, vous pouvez faire ce qui suit gratuitement .

Instructions rapides

  1. Installez vscode
  2. Installez Ruby Dev Kit si vous ne l'avez pas déjà fait
  3. Installer les extensions Ruby, ruby-linter et ruby-rubocop pour vscode
  4. Installez manuellement toutes les gemmes rubyide / vscode-ruby , si nécessaire
  5. Configurez votre launch.json pour utiliser les launch.json "cwd" et "program" utilisant la macro {workspaceRoot}
  6. Ajoutez un champ appelé "showDebuggerOutput" et définissez-le sur true
  7. Activez les points d'arrêt partout dans vos préférences de débogage en tant que "debug.allowBreakpointsEverywhere": true

Instructions détaillées

  1. Télécharger Visual Studio Code aka vscode ; ce n'est pas la même chose que Visual Studio . C'est gratuit, léger et généralement considéré positivement.
  2. Installez le kit Ruby Dev. vous devriez suivre les instructions à leur repo ici: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. Ensuite, vous pouvez soit installer des extensions via un navigateur Web, soit à l'intérieur de l'IDE; C'est pour l'intérieur de l'IDE. Si vous choisissez l'autre, vous pouvez aller here . Accédez à la partie Extensions de vscode; Vous pouvez le faire de deux façons, mais la méthode la plus évolutive sera probablement F1 , et en tapant e x t jusqu'à ce qu'une option appelée Extensions: Install Extensions devienne disponible. Les alternatives sont Ctrl Shift x et dans la barre de menu supérieure, View->Extensions
  4. Ensuite, vous allez vouloir les extensions suivantes; ce ne sont pas 100% nécessaires, mais je vais vous laisser décider ce qu'il faut garder après avoir bricolé certains:
    • Rubis; auteur de l'extension Peng Lv
    • ruby-rubocop; auteur de l'extension misogi
    • ruby-linter; auteur de l'extension Cody Hoover
  5. À l'intérieur du répertoire de votre script ruby, nous allons créer un répertoire via la ligne de commande appelée .vscode et dans ce cas, nous allons launch.json un fichier appelé launch.json lequel nous allons stocker des options de configuration.
    • launch.json contenu

{ "version": "0.2.0", "configurations": [ { "name": "Debug Local File", "type":"Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "{workspaceRoot}/../script_name.rb", "args": [], "showDebuggerOutput": true } ] }

  1. Suivez les instructions des auteurs de l'extension pour les installations de gemmes manuelles. Il est situé ici pour l'instant: https://github.com/rubyide/vscode-ruby#install-ruby-dependencies
  2. Vous voudrez probablement pouvoir mettre des points d'arrêt où vous voulez; ne pas activer cette option peut entraîner une confusion. Pour ce faire, nous allons dans la barre de menu supérieure et sélectionnez File->Preferences->Settings (ou Ctrl , ) et faites défiler jusqu'à ce que vous atteigniez la section Debug . Développez-le et recherchez un champ appelé "debug.allowBreakpointsEverywhere" - sélectionnez ce champ et cliquez sur la petite icône en forme de crayon et réglez-le sur true .

Après avoir fait toutes ces choses amusantes, vous devriez être capable de définir des points d'arrêt et de déboguer dans un menu similaire à celui-ci pour la mi-2017 et un thème plus sombre: avec toutes les choses amusantes comme votre pile d'appels, votre visionneuse variable, etc.

Le plus grand PITA est 1) l'installation des pré-reqs et 2) Se souvenir de configurer le fichier .vscode\launch.json . Seulement # 2 devrait ajouter n'importe quel bagage à de futurs projets, et vous pouvez simplement copier une config assez générique comme celle ci-dessus. Il y a probablement un emplacement de configuration plus général, mais je ne le sais pas du haut de ma tête.


Déboguer en levant des exceptions est beaucoup plus facile que de plisser les yeux dans les instructions du journal d' print , et pour la plupart des bogues, il est généralement beaucoup plus rapide que d'ouvrir un débogueur irb comme pry ou byebug . Ces outils ne devraient pas être votre premier pas.

Débogage Ruby / Rails rapidement:

1. Méthode rapide: Élever une Exception puis et .inspect son résultat

Le moyen le plus rapide de déboguer le code Ruby (Rails en particulier) consiste à raise une exception le long du chemin d'exécution de votre code en appelant .inspect sur la méthode ou l'objet (par exemple, foo ):

raise foo.inspect

Dans le code ci-dessus, raise déclenche une Exception qui interrompt l'exécution de votre code et renvoie un message d'erreur qui contient .inspect informations .inspect sur l'objet / méthode (c.-à-d. foo ) sur la ligne que vous essayez de déboguer.

Cette technique est utile pour examiner rapidement un objet ou une méthode ( par exemple, est-elle nil ? ) Et pour confirmer immédiatement si une ligne de code est même exécutée du tout dans un contexte donné.

2. Repli: Utilisez un débogueur de ruby IRB comme byebug ou pry

Si vous avez des informations sur l'état d'exécution de vos codes, vous devriez envisager de passer à un débogueur de ruby ​​gem irb comme pry ou byebug où vous pourrez plonger plus profondément dans l'état des objets dans votre chemin d'exécution.

Général débutant

Lorsque vous essayez de déboguer un problème, il est conseillé de toujours: Lire le message d'erreur! @ # $ Ing (RTFM)

Cela signifie lire les messages d'erreur attentivement et complètement avant d'agir pour que vous compreniez ce qu'il essaie de vous dire. Lorsque vous déboguez, posez les questions mentales suivantes, dans cet ordre , en lisant un message d'erreur:

  1. À quelle classe fait référence l'erreur? (c'est-à - dire que j'ai la classe d'objet correcte ou mon objet est-il nil ? )
  2. Quelle méthode fait référence à l'erreur? (ie est leur un type dans la méthode, puis-je appeler cette méthode sur ce type / classe d'objet? )
  3. Enfin, en utilisant ce que je peux déduire de mes deux dernières questions, quelles lignes de code devrais-je examiner? (Rappelez-vous: la dernière ligne de code dans la trace de la pile n'est pas nécessairement là où se trouve le problème.)

Dans la trace de la pile, accordez une attention particulière aux lignes de code qui proviennent de votre projet (par exemple les lignes commençant par app/... si vous utilisez Rails). 99% du temps le problème est avec votre propre code.

Pour illustrer pourquoi l'interprétation dans cet ordre est important ...

Par exemple, un message d'erreur Ruby qui confond de nombreux débutants:

Vous exécutez du code qui s'exécute en tant que tel:

@foo = Foo.new

...

@foo.bar

et vous obtenez une erreur qui dit:

undefined method "bar" for Nil:nilClass

Les débutants voient cette erreur et pensent que le problème est que la bar méthode n'est pas définie . Ce n'est pas. Dans cette erreur, la partie réelle qui compte est:

for Nil:nilClass

for Nil:nilClass signifie que @foo est @foo ! @foo n'est pas une variable d'instance Foo ! Vous avez un objet qui est Nil . Quand vous voyez cette erreur, c'est simplement ruby ​​essayant de vous dire que la bar méthode n'existe pas pour les objets de la classe Nil . (bien duh! puisque nous essayons d'utiliser une méthode pour un objet de la classe Foo pas Nil ).

Malheureusement, en raison de la façon dont cette erreur est écrite ( undefined method "bar" for Nil:nilClass ) il est facile de se faire avoir en pensant que cette erreur est undefined method "bar" for Nil:nilClass au fait que la bar n'est undefined . Lorsqu'elle n'est pas lue attentivement, cette erreur amène les débutants à errer dans les détails de la méthode de la bar sur Foo , manquant complètement la partie de l'erreur qui indique que l'objet est de la mauvaise classe (dans ce cas: nul). C'est une erreur qui est facilement évitée en lisant les messages d'erreur dans leur intégralité.

Résumé:

Lisez toujours attentivement l' intégralité du message d'erreur avant de commencer le débogage. Cela signifie: Vérifiez toujours d'abord le type de classe d'un objet dans un message d'erreur, puis ses méthodes , avant de commencer à effectuer une recherche dans une pile de lignes ou une ligne de code où vous pensez que l'erreur peut se produire. Ces 5 secondes peuvent vous faire économiser 5 heures de frustration.

tl; dr: Ne plissez pas les journaux d'impression: augmentez les exceptions à la place. Évitez les trous de lapin en lisant attentivement les erreurs avant de déboguer.





debugging