J'ai copié le code Ruby suivant à partir d'Internet et apporté quelques modifications.
Mais ça ne marche pas!
S'il vous plaît aider. Que puis-je faire pour déboguer le programme par moi-même?
Installer via:
$ gem install pry
$ pry
Puis ajouter:
require 'pry'; binding.pry
dans votre programme.
Cependant, à partir de pry
0.12.2, il n’existe pas de commande de navigation telle que next
, break
, etc. Cette option est également fournie par d’autres gemmes, voir par exemple pry-byedebug
.
En rubis:
Ruby -rdebug myscript.rb
ensuite,
b <line>
: mettre le point d'arrêtn(ext)
ou s(tep)
et c(ontinue)
p(uts)
pour l'affichage(comme Perl debug)
Dans Rails: Lancez le serveur avec
script/server --debugger
et ajoutez debugger
dans le code.
Comme recommandé: utilisez le levier! Je ne peux qu'être d'accord sur ce point.
pry est une bien meilleure réplique que irb.
Vous devez ajouter
require 'pry'
dans votre fichier source, puis insérez un point d'arrêt dans votre code source en ajoutant
binding.pry
à l'endroit où vous voulez jeter un coup d'œil sur 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
ligne, vous serez directement projeté dans la réplique, avec tout le contexte de votre programme à portée de main, de sorte que vous pourrez simplement explorer tout ce qui se trouve autour de vous, explorer tous les objets, changer d'état et même changer le code à la volée.
Je crois que vous ne pouvez pas changer le code de la méthode dans laquelle vous vous trouvez, vous ne pouvez donc malheureusement pas changer la prochaine ligne à exécuter. Mais bon Ruby le code a tendance à être simple ligne de toute façon ;-)
Le débogage en levant des exceptions est beaucoup plus facile que jeté un œil sur les instructions de journal print
, et pour la plupart des bogues, il est généralement beaucoup plus rapide que d’ouvrir un débogueur irb tel que pry
ou byebug
. Ces outils ne devraient pas être votre première étape.
Exception
alors et _.inspect
_ son résultatLe moyen le plus rapide de déboguer le code Ruby (en particulier Rails) consiste à raise
une exception le long du chemin d'exécution de votre code lors de l'appel de _.inspect
_ sur la méthode ou l'objet (par exemple, foo
):
_raise foo.inspect
_
Dans le code ci-dessus, raise
déclenche un Exception
qui interrompt l'exécution de votre code et renvoie un message d'erreur contenant commodément _.inspect
_ informations sur l'objet/la méthode (c'est-à-dire foo
) sur la ligne que vous êtes essayer de déboguer.
Cette technique est utile pour rapidement examiner un objet ou une méthode (. Par exemple, est-il nil
? ) et pour confirmer immédiatement si une ligne de code est même exécutée dans un contexte donné.
byebug
ou pry
Une fois que vous avez des informations sur l'état du flux d'exécution de vos codes, envisagez de passer à un débogueur Ruby gem irb tel que pry
ou byebug
, où vous pourrez approfondir l'état des objets dans votre chemin d'exécution.
Lorsque vous essayez de déboguer un problème, nous vous conseillons de toujours: Lire le message d'erreur! @ # $ Ing (RTFM)
Cela signifie lire les messages d'erreur attentivement et complètement avant d'agir afin que vous comprend ce que vous essayez de vous dire. Lorsque vous déboguez, posez les questions mentales suivantes dans cet ordre , lors de la lecture d'un message d'erreur:
nil
? )Dans la trace de la pile, faites particulièrement attention aux lignes de code issues de votre projet (par exemple, les lignes commençant par _app/...
_ si vous utilisez Rails). 99% du temps, le problème vient de votre propre code.
Pour illustrer pourquoi interpréter dans cet ordre est important ...
Vous exécutez du code qui s'exécute à un moment donné comme 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 méthode bar
est non définie . Ce n'est pas le cas. Dans cette erreur, la vraie partie qui compte est:
_for Nil:nilClass
_
_for Nil:nilClass
_ signifie que _@foo
_ est nul! _@foo
_ n'est pas une variable d'instance Foo
! Vous avez un objet qui est Nil
. Lorsque vous voyez cette erreur, c'est simplement Ruby qui essaie de vous dire que la méthode bar
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
et non 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 lui faisant croire que cette erreur a à voir avec bar
étant undefined
. Lorsqu'elle n'est pas lue attentivement, cette erreur amène les débutants à creuser par erreur dans les détails de la méthode bar
sur Foo
, en omettant entièrement la partie de l'erreur qui suggère que l'objet est de la mauvaise classe (dans le cas présent: nil). C'est une erreur qui peut être facilement évitée en lisant les messages d'erreur dans leur intégralité.
Résumé:
Toujours avec précaution lisez le message d'erreur entier avant de commencer tout débogage. Cela signifie: vérifiez toujours le type ) d'un objet dans un message d'erreur en premier , puis ses méthodes , avant vous commencez à chercher dans n'importe quelle pile ou 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 louchez pas les journaux d'impression, mais déclenchez des exceptions. Évitez les trous de lapin en lisant attentivement les erreurs avant le débogage.
Imprimez les variables autant que possible. (Ceci s’appelle le débogage printf) Vous pouvez le faire en lançant
STDERR.puts x.inspect
ou
STDERR.puts "Variable x is #{x.inspect}"
Si vous voulez rendre cela plus facile à taper, alors vous voudrez peut-être utiliser la gemme exemple .
Activer les avertissements. Si vous utilisez Ruby
, exécutez-le avec le commutateur -w
(par exemple, Ruby -w script.rb
). Si vous l'exécutez à partir d'irb et que vous utilisez une version de Ruby antérieure à la 1.9.2, tapez $VERBOSE = true
au début de votre session. Si vous mal orthographiez une variable d'instance, une fois les avertissements activés, vous obtiendrez
warning: la variable d'instance
@valeus
n'est pas initialisée
Comprendre le concept d'une côtelette binaire (la citation suivante est tirée de Pratiques d'un développeur agile )
Divisez l'espace du problème en deux et voyez quelle moitié contient le problème. Puis divisez encore cette moitié en deux et répétez l'opération.
Si vous réussissez avec un hachage binaire, vous constaterez peut-être qu’une seule ligne ne fait pas ce que vous attendez. Par exemple
[1, 2, 3].include?([1,2])
donne une valeur de false
, même si on pourrait penser qu'il renverrait true
. Dans ce cas, vous voudrez peut-être consulter la documentation. Les sites Web de documentation comprennent Ruby-doc.org , ou APIdock . Dans ce dernier cas, vous devriez taper include?
à côté de la loupe située dans le coin supérieur droit, choisissez le include?
qui comporte Array
(si vous ne savez pas quelle classe [1, 2, 3]
est, tapez [1, 2, 3].class
dans irb) et vous obtenez include? (Array) , qui décrit son rôle.
Cependant, si la documentation ne vous aide pas, vous obtiendrez probablement une bonne réponse si vous pouvez poser une question sur le fait qu'une ligne spécifique ne fait pas ce qu'elle devrait être, plutôt que sur la raison pour laquelle un script entier ne fait pas ce que vous faites. cela devrait.
supprime toutes les choses
Bienvenue en 2017 ^ _ ^
Donc, si vous n'êtes pas opposé à essayer un nouveau IDE, vous pouvez procéder comme suit pour free .
launch.json
pour utiliser les champs "cwd"
et et "program"
à l'aide de la macro {workspaceRoot}
."showDebuggerOutput"
et définissez-le sur true
."debug.allowBreakpointsEverywhere": true
vscode
; ce n'est pas la même chose que Visual Studio . C'est gratuit, léger et généralement considéré positivement.View->Extensions
.vscode
et vous y trouverez uniquement un fichier nommé launch.json
. pour 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 } ] }
File->Preferences->Settings
(ou Ctrl, ) et faites défiler jusqu'à la section Debug
. Développez-le et cherchez un champ appelé "debug.allowBreakpointsEverywhere"
- sélectionnez-le, cliquez sur la petite icône représentant un crayon et réglez-le sur true
.Après avoir fait toutes ces choses amusantes, vous devriez pouvoir définir des points d'arrêt et déboguer dans un menu similaire à celui-ci pour le milieu de 2017 et sur un thème plus sombre: avec tout ce qui est amusant comme votre pile d’appel, votre afficheur de variables, etc.
Le plus gros fichier PITA est 1) l’installation des pré-requêtes et 2) la mémorisation de la configuration du fichier .vscode\launch.json
. Seul le numéro 2 devrait ajouter n'importe quel bagage aux projets futurs, et vous pouvez simplement copier une configuration assez générique telle que celle listée ci-dessus. Il y a probablement un emplacement de configuration plus général, mais je ne le sais pas par cœur.
Toutes les autres réponses donnent déjà presque tout ... Juste un petit ajout.
Si vous voulez plus de débogueur de type IDE (non-CLI) et que vous n’ayez pas peur d’utiliser Vim en tant qu’éditeur, je suggère Vim Ruby Debugger plug-in.
Sa documentation est assez simple, alors suivez le lien et voyez. En bref, cela vous permet de définir un point d'arrêt sur la ligne courante dans l'éditeur, d'afficher les variables locales dans une fenêtre astucieuse en pause, de passer de/vers - dans presque toutes les fonctions habituelles du débogueur.
Pour moi, il était très agréable d’utiliser ce débogueur vim pour déboguer une application Rails, bien que capacités d’enregistreur riche sur Rails en élimine presque le besoin.
Je viens de découvrir ce petit bijou (transforme Pry en un débogueur pour MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Installer avec:
gem install pry-byebug
puis utilisez exactement comme pry
, marquez la ligne que vous souhaitez interrompre à:
require 'pry'; binding.pry
Cependant, contrairement à Vanilla Pry, cette gemme contient des commandes de navigation clés telles que next
, step
et break
:
break SomeClass#run # Break at the start of `SomeClass#run`.
break Foo#bar if baz? # Break at `Foo#bar` only if `baz?`.
break app/models/user.rb:15 # Break at line 15 in user.rb.
break 14 # Break at line 14 in the current file.
-w
(avertissements)A partir de Ruby 2.4.0, il est plus facile de démarrer une session IRB REPL au milieu de tout programme Ruby. Placez ces lignes au point du programme que vous souhaitez déboguer:
require 'irb'
binding.irb
Vous pouvez exécuter le code Ruby et imprimer des variables locales. Tapez Ctrl + D ou quit
pour terminer le programme REPL et laisser le programme Ruby continuer à s'exécuter.
Vous pouvez également utiliser puts
et p
pour imprimer les valeurs de votre programme en cours d'exécution.
Je recommande fortement cette vidéo, afin de choisir le bon outil pour déboguer notre code.
https://www.youtube.com/watch?v=GwgF8GcynV
Personnellement, je soulignerais deux grands sujets dans cette vidéo.
C'est mes deux centimes!
Pour déboguer facilement le script shell Ruby, modifiez sa première ligne à partir 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 Continue (à la prochaine exception, point d'arrêt ou ligne avec: debugger
),n
pour la ligne suivante,w
/where
to Afficher le cadre/la pile d'appels,l
to Afficher le code actuel,cat
pour afficher les points d'accroche.h
pour plus d'aide.Voir aussi: Débogage avec Ruby-debug , Raccourcis clés pour Ruby-debug gem .
Si le script ne fait que se bloque et que vous avez besoin d’une trace, essayez d’utiliser lldb
/gdb
comme:
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 les processus non possédés.
Si vous utilisez RubyMine , le débogage des scripts Ruby est simple et direct.
Supposons que vous ayez un script Ruby hello_world.rb
Définissez un point d'arrêt à la ligne 6 comme ci-dessous.
Vous pouvez maintenant démarrer le débogueur pour exécuter le script:
Ensuite, lorsque l'exécution atteindra un point d'arrêt, vous pourrez inspecter des variables, etc.
Eh bien, Ruby lib standard a un débogueur de console simple à utiliser comme gdb: http://Ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__. html Pas besoin d'installer de gemmes supplémentaires. Les scripts Rails peuvent également être débogués de cette façon.
par exemple.
def say(Word)
require 'debug'
puts Word
end
débogage printf
Il y a toujours eu une controverse autour des techniques de débogage. Certaines personnes aiment déboguer des instructions imprimées, d'autres aiment creuser plus profondément avec un débogueur.
Je suggère que vous essayez les deux approches.
En fait, un des anciens hommes d'Unix a récemment déclaré que le débogage de printf était un moyen plus rapide de le prendre à certains moments.
Mais si vous êtes nouveau dans un emploi et que vous avez besoin de comprendre un gros bloc de code, alors il est vraiment utile de s'y déplacer, de placer des points de rupture ici et là et de suivre son fonctionnement.
Cela devrait vous aider à comprendre comment le code est tissé.
Si vous êtes novice dans le logiciel d’autres peuples, il peut vous aider à y accéder.
Vous découvrirez rapidement s’ils l’ont arrangé de manière intelligente ou s’il s’agit simplement d’une bande de merde.
Il existe de nombreux débogueurs dotés de fonctionnalités différentes, sur lesquels vous faites un choix. Mes priorités étaient satisfaites avec leviers qui était:
La mère de tous les débogueurs est tout simplement un vieil écran d'impression. La plupart du temps, vous ne voulez probablement qu'inspecter des objets simples. Voici comment procéder:
@result = fetch_result
p "--------------------------"
p @result
Ceci imprimera le contenu de @result to STDOUT avec une ligne devant pour faciliter l'identification.
Si vous utilisez un framework capable de charger/recharger automatiquement, tel que 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 à la structure)
Je trouve que cela fonctionne pour 90% des cas d'utilisation pour moi. Vous pouvez aussi utiliser Ruby-debug, mais la plupart du temps, je le trouve excessif.