Ich habe den folgenden Ruby-Code aus dem Internet kopiert und einige Änderungen vorgenommen, aber er funktioniert nicht.
Was kann ich tun, um das Programm selbst zu debuggen?
Ich habe den folgenden Ruby-Code aus dem Internet kopiert und einige Änderungen vorgenommen, aber er funktioniert nicht.
Was kann ich tun, um das Programm selbst zu debuggen?
Antworten:
Installation über:
$ gem install pry
$ pry
Dann füge hinzu:
require 'pry'; binding.pry
in Ihr Programm.
Ab pry
0.12.2 gibt es jedoch keine Navigationsbefehle wie next
, break
usw. Einige andere Edelsteine diese zusätzlich zur Verfügung stellen, siehe zum Beispiel pry-byedebug
.
binding.pry
. Es kommt auch mit Farbvervollständigung, Dokumentationssuche und der Möglichkeit, eine Methode dynamisch zu bearbeiten und neu zu laden.
Pry
Ich byebug
bin großartig, aber nicht als erster Schritt beim Debuggen. In den meisten Fällen raise object.inspect
löst das Auslösen einer Ausnahme mit Ihr Problem schneller als das Öffnen einer irb-Sitzung. Ich empfehle, die Konsolen-Debugger nur noch einmal zu verwenden. Einfache Lösungen wie das Auslösen einer Ausnahme können Ihr Problem nicht lösen.
pry
? Ich konnte nicht finden, wie es geht; und das erwarte ich von einem debugger.
In Ruby:
ruby -rdebug myscript.rb
dann,
b <line>
: Haltepunkt setzen n(ext)
oder s(tep)
undc(ontinue)
p(uts)
Zur Ausstellung(wie Perl-Debug)
In Rails: Starten Sie den Server mit
script/server --debugger
und fügen Sie debugger
den Code hinzu.
-r debug
ist Müll?
facets
der Edelsteinanforderungen ausgeführt werden kann, und war erfolglos. Für alte Rails-Apps ruby-debug
ist das ein bisschen böse, erledigt aber die Arbeit.
Als Geländer empfohlen: Hebel verwenden! Dem kann ich nur zustimmen.
Pry ist eine viel bessere Antwort als irb.
Sie müssen hinzufügen
require 'pry'
in Ihre Quelldatei und fügen Sie dann durch Hinzufügen einen Haltepunkt in Ihren Quellcode ein
binding.pry
an der Stelle, an der Sie einen Blick auf die Dinge werfen möchten (dies ist wie das Auslösen eines Haltepunkts in einer klassischen IDE-Umgebung)
Sobald Ihr Programm die
binding.pry
Sie werden direkt in die Pry-Antwort geworfen, wobei der gesamte Kontext Ihres Programms zur Hand ist, sodass Sie einfach alles erkunden, alle Objekte untersuchen, den Status ändern und sogar den Code im laufenden Betrieb ändern können.
Ich glaube, Sie können den Code der Methode, in der Sie sich gerade befinden, nicht ändern, daher können Sie die nächste auszuführende Zeile leider nicht ändern. Aber guter Ruby-Code ist sowieso eher einzeilig ;-)
Das Debuggen durch Auslösen von Ausnahmen ist weitaus einfacher als das Schielen durchprint
Protokollanweisungen, und für die meisten Fehler ist es im Allgemeinen viel schneller als das Öffnen eines irb-Debuggers wiepry
oderbyebug
. Diese Tools sollten nicht immer Ihr erster Schritt sein.
Exception
Dann und.inspect
sein ErgebnisDer schnellste Weg, um Ruby-Code (insbesondere Rails-Code) zu debuggen, besteht in raise
einer Ausnahme entlang des Ausführungspfads Ihres Codes, während Sie .inspect
die Methode oder das Objekt aufrufen (z. B. foo
):
raise foo.inspect
Löst im obigen Code raise
eine aus Exception
, die die Ausführung Ihres Codes anhält , und gibt eine Fehlermeldung zurück, die bequemerweise .inspect
Informationen über das Objekt / die Methode enthält (d. H.foo
) in der Zeile enthält, die Sie debuggen möchten.
Diese Technik ist nützlich, um ein Objekt oder eine Methode schnell zu untersuchen ( z. B. nil
? ) Und um sofort zu bestätigen, ob eine Codezeile in einem bestimmten Kontext überhaupt ausgeführt wird.
byebug
oderpry
Erst wenn Sie Informationen über den Status des Ausführungsflusses Ihres Codes haben, sollten Sie in Betracht ziehen, zu einem Ruby Gem Irb-Debugger wie pry
oder zu byebug
wechseln, wo Sie tiefer in den Status von Objekten in Ihrem Ausführungspfad eintauchen können.
Wenn Sie versuchen, ein Problem zu debuggen, sollten Sie immer Folgendes tun : Lesen Sie die! @ # $ Ing-Fehlermeldung (RTFM).
Das bedeutet , dass Sie Fehlermeldungen sorgfältig und vollständig lesen, bevor Sie handeln, damit Sie verstehen, was es Ihnen zu sagen versucht. Stellen Sie beim Debuggen beim Lesen einer Fehlermeldung die folgenden mentalen Fragen in dieser Reihenfolge :
nil
? ) Achten Sie im Stack-Trace besonders auf Codezeilen, die aus Ihrem Projekt stammen (z. B. Zeilen, die mit beginnen, app/...
wenn Sie Rails verwenden). In 99% der Fälle liegt das Problem bei Ihrem eigenen Code.
Um zu veranschaulichen, warum das Dolmetschen in dieser Reihenfolge wichtig ist ...
Sie führen Code aus, der irgendwann als solcher ausgeführt wird:
@foo = Foo.new
...
@foo.bar
und Sie erhalten einen Fehler, der besagt:
undefined method "bar" for Nil:nilClass
Anfänger sehen diesen Fehler und denken , das Problem ist , dass die Methode bar
ist nicht definiert . Es ist nicht. In diesem Fehler ist der eigentliche Teil, der zählt:
for Nil:nilClass
for Nil:nilClass
bedeutet das @foo
ist Null! @foo
ist keine Foo
Instanzvariable! Sie haben ein Objekt, das ist Nil
. Wenn Sie diesen Fehler sehen, ist es einfach Ruby, der versucht, Ihnen mitzuteilen, dass die Methode bar
für Objekte der Klasse nicht vorhanden ist Nil
. (na duh! da wir versuchen eine Methode für ein Objekt der Klasse Foo
nicht zu verwenden Nil
).
Leider ist es aufgrund der Art und Weise, wie dieser Fehler geschrieben wird ( undefined method "bar" for Nil:nilClass
), leicht zu täuschen, dass dieser Fehler mit bar
Sein zu tun hat undefined
. Wenn dieser Fehler nicht sorgfältig gelesen wird, führt dies dazu, dass Anfänger fälschlicherweise in die Details der bar
Methode Foo
eintauchen und den Teil des Fehlers, der darauf hinweist, dass das Objekt der falschen Klasse angehört (in diesem Fall: null), vollständig übersehen. Es ist ein Fehler, der leicht vermieden werden kann, indem Fehlermeldungen vollständig gelesen werden.
Zusammenfassung:
Lesen Sie immer die gesamte Fehlermeldung sorgfältig durch , bevor Sie mit dem Debuggen beginnen. Das heißt: Überprüfen Sie immer die Klasse Typ eines Objekts in einer Fehlermeldung zuerst , dann seine Methoden , bevor Sie sleuthing in jede Stacktrace oder Codezeile beginnen , wo Sie den Fehler denken auftreten kann. Diese 5 Sekunden können Ihnen 5 Stunden Frust ersparen.
tl; dr: Schielen Sie nicht auf Druckprotokolle: lösen Sie Ausnahmen aus oder verwenden Sie stattdessen einen irb-Debugger. Vermeiden Sie Kaninchenlöcher, indem Sie Fehler vor dem Debuggen sorgfältig lesen.
Drucken Sie die Variablen nach Möglichkeit aus. (Dies wird als printf-Debugging bezeichnet.) Sie können dies durch Ausführen tun
STDERR.puts x.inspect
oder
STDERR.puts "Variable x is #{x.inspect}"
Wenn Sie dies einfacher tippen machen wollen, dann können Sie das verwenden exemplor gem.
Warnungen einschalten. Wenn Sie laufen, ruby
führen Sie es mit dem -w
Schalter aus (z ruby -w script.rb
. B. ). Wenn Sie es von irb aus ausführen und eine Version von Ruby vor 1.9.2 verwenden, geben Sie $VERBOSE = true
zu Beginn Ihrer Sitzung ein. Wenn Sie eine Instanzvariable falsch schreiben, erhalten Sie Warnungen, sobald sie aktiviert sind
Warnung: Instanzvariable
@valeus
nicht initialisiert
Verstehen Sie das Konzept eines binären Chops (das folgende Zitat stammt aus den Praktiken eines agilen Entwicklers ).
Teilen Sie den Problemraum in zwei Hälften und sehen Sie, welche Hälfte das Problem enthält. Teilen Sie diese Hälfte erneut in zwei Hälften und wiederholen Sie den Vorgang.
Wenn Sie mit einem binären Chop erfolgreich sind, stellen Sie möglicherweise fest, dass eine einzelne Zeile nicht das tut, was Sie von ihr erwarten. Beispielsweise
[1, 2, 3].include?([1,2])
gibt einen Wert von an false
, obwohl Sie denken würden, dass es zurückkehren würde true
. In diesem Fall sollten Sie sich die Dokumentation ansehen. Zu den Dokumentationswebsites gehören ruby-doc.org oder APIdock . Im letzteren Fall würden Sie geben include?
neben der Lupe in der Nähe der oberen rechten Ecke, wählen Sie die , include?
die hat Array
unter ihm (wenn Sie nicht wissen , was Klasse [1, 2, 3]
ist, geben Sie [1, 2, 3].class
in irb), und Sie erhalten schließen? (Array) , das beschreibt, was es tut.
Wenn die Dokumentation jedoch nicht hilft, erhalten Sie mit größerer Wahrscheinlichkeit eine gute Antwort, wenn Sie eine Frage dazu stellen können, wie eine bestimmte Zeile nicht das tut, was sie sollte, anstatt warum ein gesamtes Skript nicht das tut, was es sollte.
löscht alle Dinge
Willkommen zu 2017 ^ _ ^
Okay, wenn Sie nicht dagegen sind, eine neue IDE auszuprobieren, können Sie Folgendes kostenlos tun .
launch.json
zu verwendenden "cwd"
und und "program"
Felder mithilfe des {workspaceRoot}
Makros"showDebuggerOutput"
und setzen Sie es auftrue
"debug.allowBreakpointsEverywhere": true
vscode
. Dies ist nicht dasselbe wie in Visual Studio . Es ist kostenlos, leicht und allgemein positiv bewertet.View->Extensions
.vscode
erstellen launch.json
wir über die Befehlszeile ein Verzeichnis mit dem Namen und dort nur eine Datei mit dem Namen , in der einige Konfigurationsoptionen gespeichert werden.
launch.json
Inhalt
{
"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
(oder Ctrl,) und scrollen, bis Sie den Debug
Abschnitt erreichen. Erweitern Sie es und suchen Sie nach einem Feld mit dem Namen "debug.allowBreakpointsEverywhere"
- wählen Sie dieses Feld aus, klicken Sie auf das kleine Bleistiftsymbol und setzen Sie es auf true
.Nachdem Sie all diese lustigen Dinge erledigt haben, sollten Sie in der Lage sein, Haltepunkte zu setzen und in einem ähnlichen Menü für Mitte 2017 und einem dunkleren Thema zu debuggen: mit all den lustigen Dingen wie Ihrem Aufrufstapel, dem variablen Viewer usw.
Die größte PITA ist 1) Installieren der Voraussetzungen und 2) Denken Sie daran, die .vscode\launch.json
Datei zu konfigurieren . Nur # 2 sollte zukünftiges Projekt mit Gepäck versehen, und Sie können einfach eine ausreichend generische Konfiguration wie die oben aufgeführte kopieren. Es gibt wahrscheinlich einen allgemeineren Konfigurationsort, aber ich weiß es nicht genau.
Ich empfehle dieses Video dringend, um im Moment das richtige Tool zum Debuggen unseres Codes auszuwählen.
https://www.youtube.com/watch?v=GwgF8GcynV0
Persönlich möchte ich in diesem Video zwei große Themen hervorheben.
Das sind meine zwei Cent!
Alle anderen Antworten geben schon fast alles ... Nur eine kleine Ergänzung.
Wenn Sie einen weiteren IDE-ähnlichen Debugger (ohne CLI) möchten und keine Angst haben, Vim als Editor zu verwenden, empfehle ich das Vim Ruby Debugger- Plugin.
Die Dokumentation ist ziemlich einfach, folgen Sie also dem Link und sehen Sie. Kurz gesagt, es ermöglicht Ihnen, den Haltepunkt an der aktuellen Zeile im Editor festzulegen, lokale Variablen in der Pause in einem raffinierten Fenster anzuzeigen und über / in zu gehen - fast alle üblichen Debugger-Funktionen.
Für mich war es ziemlich unterhaltsam, diesen vim-Debugger zum Debuggen einer Rails-App zu verwenden, obwohl die umfangreichen Logger-Fähigkeiten von Rails dies fast überflüssig machen.
Ich habe gerade dieses Juwel entdeckt (verwandelt Pry in einen Debugger für MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Installieren mit:
gem install pry-byebug
Verwenden Sie dann genau wie pry
, markieren Sie die Linie, an der Sie brechen möchten:
require 'pry'; binding.pry
Im Gegensatz zu Vanille hebeln aber dieses Juwel hat einige wichtige GDB-ähnliche Navigation Befehle wie next
, step
und 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
Flagge (Warnungen) einirb
ein großartiger Ausgangspunkt ist. Versuchen Sie es mit irb mit kleinen fragwürdigen Stücken. Ich liebe Ruby-Debug (Ruby-Debug19 für Ruby 1.9+), weil es einfach ist, das laufende Programm zu stoppen, Variablen zu untersuchen, in irb abzulegen und dann weiterzulaufen.
Um das Ruby-Shell-Skript einfach zu debuggen, ändern Sie einfach die erste Zeile von:
#!/usr/bin/env ruby
zu:
#!/usr/bin/env ruby -rdebug
Jedes Mal, wenn die Debugger-Konsole angezeigt wird, können Sie Folgendes auswählen:
c
für Weiter (zur nächsten Ausnahme, zum nächsten Haltepunkt oder zur nächsten Zeile mit :) debugger
,n
für die nächste Zeilew
/ where
um Frame / Call Stack anzuzeigen,l
um den aktuellen Code anzuzeigen,cat
Fangpunkte anzeigen.h
für weitere Hilfe.Siehe auch: Debuggen mit Ruby-Debug , Tastenkombinationen für Ruby-Debug-Juwel .
Falls das Skript nur hängt und Sie eine Rückverfolgung benötigen, versuchen Sie es mit lldb
/ gdb
like:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
und überprüfen Sie dann Ihren Prozessvordergrund.
Ersetzen Sie lldb
durch, gdb
wenn es besser funktioniert. Präfix mit sudo
, um nicht im Besitz befindlichen Prozess zu debuggen.
Ab Ruby 2.4.0 ist es einfacher, eine IRB REPL-Sitzung mitten in einem Ruby-Programm zu starten. Setzen Sie diese Zeilen an die Stelle im Programm, die Sie debuggen möchten:
require 'irb'
binding.irb
Sie können Ruby-Code ausführen und lokale Variablen ausdrucken. Geben Sie Strg + D oder ein quit
, um die REPL zu beenden und das Ruby-Programm weiter laufen zu lassen.
Sie können auch Werte aus Ihrem Programm verwenden puts
und p
ausdrucken, während es ausgeführt wird.
Wenn Sie RubyMine verwenden , ist das Debuggen von Ruby-Skripten einfach und unkompliziert.
Angenommen, Sie haben ein Ruby-Skript hello_world.rb
Stellen Sie einen Haltepunkt in Zeile 6 wie folgt ein.
Jetzt können Sie einfach den Debugger starten, um das Skript auszuführen:
Wenn die Ausführung einen Haltepunkt erreicht, können Sie Variablen usw. überprüfen.
printf Debugging
Es gab schon immer Kontroversen um Debugging-Techniken, manche Leute debuggen gerne mit Print-Anweisungen, andere graben gerne mit einem Debugger tief.
Ich würde vorschlagen, dass Sie beide Ansätze versuchen.
Tatsächlich sagte einer der alten Unix-Männer kürzlich, dass das Debuggen von Printf an einigen Stellen ein schnellerer Weg für ihn sei.
Aber wenn Sie in einem Job neu sind und einen großen Code-Blob verstehen müssen, ist es wirklich nützlich, dort durchzugehen, hier und da einige Haltepunkte zu setzen und mitzuarbeiten, wie es funktioniert.
Es sollte Ihnen ein Verständnis dafür geben, wie der Code gewebt wird.
Wenn Sie mit der Software anderer Leute noch nicht vertraut sind, kann dies Ihnen dabei helfen, diese zu durchlaufen.
Sie werden schnell herausfinden, ob sie es auf clevere Weise arrangiert haben oder ob das nur ein Haufen Scheiße ist.
Nun, Ruby Standard Lib hat einen einfach zu verwendenden GDB-ähnlichen Konsolen-Debugger: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Es müssen keine zusätzlichen Edelsteine installiert werden. Auf diese Weise können auch Rails-Skripte debuggt werden.
z.B
def say(word)
require 'debug'
puts word
end
Die Mutter aller Debugger ist ein normaler alter Druckbildschirm. Meistens möchten Sie wahrscheinlich nur einige einfache Objekte untersuchen. Ein schneller und einfacher Weg ist wie folgt:
@result = fetch_result
p "--------------------------"
p @result
Dadurch wird der Inhalt von @result an STDOUT mit einer Zeile vor der einfachen Identifizierung ausgedruckt.
Bonus Wenn Sie ein Framework zum automatischen Laden / Neuladen wie Rails verwenden, müssen Sie Ihre App nicht einmal neu starten. (Es sei denn, der Code, den Sie debuggen, wird aufgrund von Framework-spezifischen Einstellungen nicht neu geladen.)
Ich finde, dass dies für 90% des Anwendungsfalls für mich funktioniert. Sie können auch Ruby-Debug verwenden, aber ich finde es die meiste Zeit übertrieben.
Es gibt viele Debugger mit unterschiedlichen Funktionen, auf deren Grundlage Sie eine Auswahl treffen. Meine Prioritäten waren zufrieden mit Hebelbewegungen, die waren: