Schön, aber wie bringt man clojure dazu, 'clojure.contrib.trace zu finden? Ich habe das Clojure-Contrib-Glas auf meinem Klassenpfad, aber REPL sagtuser=> (use 'closure.contrib.trace) java.io.FileNotFoundException: Could not locate closure/contrib/trace__init.class or closure/contrib/trace.clj on classpath: (NO_SOURCE_FILE:0)
LarsH
2
Könnten Sie Clojure als Abschluss falsch schreiben, oder ist das ein Tippfehler im Kommentar? Können Sie andere clojure.contrib-Bibliotheken laden?
@Zaz Ich stimme vollkommen zu. Spyscope ist großartig! Vielleicht sogar besser als ein Debugger. Sicher zum Tippen.
J Atkin
66
Emacs 'CIDER hat einen Quell-Debugger, mit dem Sie Ausdruck für Ausdruck in einem Emacs-Puffer schrittweise vorgehen und sogar neue Werte einfügen können. Sie können alles darüber lesen Sie hier . Ein Demo-Screenshot:
Meine Lieblingsmethode ist das großzügige Streuen von printlns über den gesamten Code ... Das Ein- und Ausschalten ist dank des #_Lesemakros einfach (das den Leser in der folgenden Form lesen lässt und dann so tut, als hätte er es nie gesehen). Oder Sie können ein Makro verwenden, das entweder zu einem übergebenen Text erweitert wird oder nilvom Wert einer speziellen Variablen abhängt, z. B *debug*.:
Dann gibt es etwas, das derzeit nicht mit der REPL von swank-clojure kompatibel ist , aber zu gut ist, um es nicht zu erwähnen : debug-repl. Sie können es in einer eigenständigen REPL verwenden, die zB mit Leiningen ( lein repl) leicht zu bekommen ist ; Wenn Sie Ihr Programm über die Befehlszeile starten, wird eine eigene REPL direkt in Ihrem Terminal angezeigt. Die Idee ist, dass Sie das debug-replMakro an einer beliebigen Stelle ablegen und es seine eigene REPL aufrufen lassen können, wenn die Ausführung des Programms diesen Punkt erreicht, mit allen Einheimischen im Geltungsbereich usw. Einige relevante Links: Das Clojure-Debug-Repl , das Clojure-Debug -repl Tricks , wie wäre es mit einer Debug-Repl (in der Clojure Google-Gruppe), Debug-Repl auf Clojars .
swank-clojure macht den integrierten SLIME-Debugger in angemessener Weise nützlich, wenn Sie mit Clojure-Code arbeiten. Beachten Sie, dass die irrelevanten Teile des Stacktraces ausgegraut sind, sodass das eigentliche Problem im zu debuggenden Code leicht zu finden ist. Beachten Sie, dass anonyme Funktionen ohne "Namensschilder" im Stacktrace angezeigt werden, an die im Grunde keine nützlichen Informationen angehängt sind. Wenn ein "Namensschild" hinzugefügt wird, erscheint es im Stacktrace und alles ist wieder in Ordnung:
(fn[& args] ...)
vs.
(fn tag [& args] ...)
example stacktrace entries:
1: user$eval__3130$fn__3131.invoke(NO_SOURCE_FILE:1)
vs. ^^
1: user$eval__3138$tag__3139.invoke(NO_SOURCE_FILE:1)
^^^
Tatsächlich gibt es eine Version des Debug-Repl, die jetzt mit swank funktioniert: hugoduncan.org/post/2010/… (Spoiler-Warnung: es ist fantastisch)
1
Richtig, und es ist gut, hier einen Link zu haben, danke! Einverstanden über genial. :-)
Michał Marczyk
Wenn dies Ihr Stil ist, könnte Ihnen die in einer nachfolgenden Antwort erwähnte Debux-Bibliothek gefallen. github.com/philoskim/debux
Mallory-Erik
@ Mallory-Erik Danke, ich werde es überprüfen!
Michał Marczyk
37
Sie können auch Code einfügen, um sich mit Alex Osbornesdebug-repl in eine REPL mit allen lokalen Bindungen einzufügen :
(defmacro local-bindings
"Produces a map of the names of local bindings to their values."[](let[symbols (map key @clojure.lang.Compiler/LOCAL_ENV)](zipmap(map(fn[sym] `(quote ~sym)) symbols) symbols)))(declare *locals*)(defn eval-with-locals
"Evals a form with given locals. The locals should be a map of symbols to
values."[locals form](binding [*locals* locals](eval
`(let ~(vec(mapcat #(list % `(*locals* '~%))(keys locals)))
~form))))(defmacro debug-repl
"Starts a REPL with the local bindings available."[]
`(clojure.main/repl
:prompt #(print "dr => "):eval(partial eval-with-locals (local-bindings))))
Fügen Sie es dann an der Stelle ein, an der die Repl beginnen soll, um es zu verwenden:
(defn my-function [a b c](let[d (some-calc)](debug-repl)))
Ich stecke dies in meine user.clj, damit es in allen REPL-Sitzungen verfügbar ist.
"Beste Möglichkeiten zum Debuggen von Clojure-Code unter Verwendung der Repl"
Etwas linkes Feld, aber 'mit der REPL selbst'.
Ich schreibe seit über einem Jahr den Hobbyisten Clojure und habe kein großes Bedürfnis nach Debugging-Tools verspürt. Wenn Sie Ihre Funktionen klein halten und jede mit den erwarteten Eingaben an der REPL ausführen und die Ergebnisse beobachten, sollte es möglich sein, ein ziemlich klares Bild davon zu erhalten, wie sich Ihr Code verhält.
Ich finde, ein Debugger ist am nützlichsten, um STATE in einer laufenden Anwendung zu beobachten. Clojure macht es einfach (und macht Spaß!), In einem funktionalen Stil mit unveränderlichen Datenstrukturen zu schreiben (kein sich ändernder Zustand). Dies reduziert den Bedarf an einem Debugger massiv. Sobald ich weiß, dass sich alle Komponenten so verhalten, wie ich es erwartet habe (unter besonderer Berücksichtigung der Arten von Dingen), ist das Verhalten in großem Maßstab selten ein Problem.
Für IntelliJ gibt es ein exzellentes Clojure-Plugin namens Cursive . Unter anderem bietet es eine REPL, die Sie im Debug-Modus ausführen und Ihren Clojure-Code genau wie bei Java durchlaufen können.
Ich würde die Antwort von Peter Westmacott unterstützen, da meiner Erfahrung nach das Ausführen von Teilen meines Codes in der REPL die meiste Zeit eine ausreichende Form des Debuggens ist.
Aber wie man damit LeiningenError running 'ring server': Trampoline must be enabled for debugging
debuggt
Das scheint spezifisch zu sein ringoder lein- vielleicht lohnt es sich, eine separate Frage zu stellen?
dskrvk
6
Ab 2016 können Sie Debux verwenden , eine einfache Debugging-Bibliothek für Clojure / Script, die sowohl mit Ihrem Repl als auch mit der Konsole Ihres Browsers zusammenarbeitet. Sie können Makros in Ihren Code streuen dbg(debuggen) oder clog(console.log) und auf einfache Weise die Ergebnisse einzelner Funktionen usw. beobachten, die auf Ihrer REPL und / oder Konsole gedruckt sind.
Dies ist ein einfaches Beispiel. Das Makro dbg druckt ein Originalformular und druckt den ausgewerteten Wert im REPL-Fenster hübsch aus. Dann wird der Wert zurückgegeben, ohne die Codeausführung zu beeinträchtigen.
Hugo Duncan und seine Mitarbeiter leisten weiterhin hervorragende Arbeit mit dem Ritz- Projekt. Ritz-nrepl ist ein nREPL-Server mit Debug-Funktionen. Sehen Sie sich Hugos Debugger in Clojure- Vorträgen auf der Clojure / Conj 2012 an, um sie in Aktion zu sehen. Im Video sind einige der Folien nicht lesbar, daher möchten Sie die Folien möglicherweise von hier aus anzeigen .
Verwenden Sie Spyscope, das ein benutzerdefiniertes Reader-Makro implementiert, sodass Ihr Debug-Code auch Produktionscode
https://github.com/dgrnbrg/spyscope ist
Antworten:
Es gibt auch Dotrace, mit dem Sie die Ein- und Ausgänge ausgewählter Funktionen anzeigen können.
erzeugt die Ausgabe:
In Clojure 1.4
dotrace
hat sich bewegt:Sie benötigen die Abhängigkeit:
Und Sie müssen der Funktionsdefinition die Dynamik ^: hinzufügen
Dann ist Bob wieder dein Onkel:
quelle
user=> (use 'closure.contrib.trace) java.io.FileNotFoundException: Could not locate closure/contrib/trace__init.class or closure/contrib/trace.clj on classpath: (NO_SOURCE_FILE:0)
Ich habe ein kleines Debugging-Makro, das ich sehr nützlich finde:
Sie können es einfügen, wo immer Sie sehen möchten, was wann passiert:
quelle
clojure.tools.trace/trace
.Emacs 'CIDER hat einen Quell-Debugger, mit dem Sie Ausdruck für Ausdruck in einem Emacs-Puffer schrittweise vorgehen und sogar neue Werte einfügen können. Sie können alles darüber lesen Sie hier . Ein Demo-Screenshot:
quelle
Meine Lieblingsmethode ist das großzügige Streuen von
println
s über den gesamten Code ... Das Ein- und Ausschalten ist dank des#_
Lesemakros einfach (das den Leser in der folgenden Form lesen lässt und dann so tut, als hätte er es nie gesehen). Oder Sie können ein Makro verwenden, das entweder zu einem übergebenen Text erweitert wird odernil
vom Wert einer speziellen Variablen abhängt, z. B*debug*
.:Mit einem
(def *debug* false)
in dort wird dies erweitertnil
. Mittrue
wird es erweitert, umbody
in ein eingewickeltdo
.Die akzeptierte Antwort auf diese SO-Frage: Idiomatische Clojure für die Fortschrittsberichterstattung? ist sehr hilfreich beim Debuggen von Sequenzoperationen.
Dann gibt es etwas, das derzeit nicht mit der REPL von swank-clojure kompatibel ist , aber zu gut ist, um es nicht zu erwähnen :
debug-repl
. Sie können es in einer eigenständigen REPL verwenden, die zB mit Leiningen (lein repl
) leicht zu bekommen ist ; Wenn Sie Ihr Programm über die Befehlszeile starten, wird eine eigene REPL direkt in Ihrem Terminal angezeigt. Die Idee ist, dass Sie dasdebug-repl
Makro an einer beliebigen Stelle ablegen und es seine eigene REPL aufrufen lassen können, wenn die Ausführung des Programms diesen Punkt erreicht, mit allen Einheimischen im Geltungsbereich usw. Einige relevante Links: Das Clojure-Debug-Repl , das Clojure-Debug -repl Tricks , wie wäre es mit einer Debug-Repl (in der Clojure Google-Gruppe), Debug-Repl auf Clojars .swank-clojure macht den integrierten SLIME-Debugger in angemessener Weise nützlich, wenn Sie mit Clojure-Code arbeiten. Beachten Sie, dass die irrelevanten Teile des Stacktraces ausgegraut sind, sodass das eigentliche Problem im zu debuggenden Code leicht zu finden ist. Beachten Sie, dass anonyme Funktionen ohne "Namensschilder" im Stacktrace angezeigt werden, an die im Grunde keine nützlichen Informationen angehängt sind. Wenn ein "Namensschild" hinzugefügt wird, erscheint es im Stacktrace und alles ist wieder in Ordnung:
quelle
Sie können auch Code einfügen, um sich mit Alex Osbornes
debug-repl
in eine REPL mit allen lokalen Bindungen einzufügen :Fügen Sie es dann an der Stelle ein, an der die Repl beginnen soll, um es zu verwenden:
Ich stecke dies in meine user.clj, damit es in allen REPL-Sitzungen verfügbar ist.
quelle
"Beste Möglichkeiten zum Debuggen von Clojure-Code unter Verwendung der Repl"
Etwas linkes Feld, aber 'mit der REPL selbst'.
Ich schreibe seit über einem Jahr den Hobbyisten Clojure und habe kein großes Bedürfnis nach Debugging-Tools verspürt. Wenn Sie Ihre Funktionen klein halten und jede mit den erwarteten Eingaben an der REPL ausführen und die Ergebnisse beobachten, sollte es möglich sein, ein ziemlich klares Bild davon zu erhalten, wie sich Ihr Code verhält.
Ich finde, ein Debugger ist am nützlichsten, um STATE in einer laufenden Anwendung zu beobachten. Clojure macht es einfach (und macht Spaß!), In einem funktionalen Stil mit unveränderlichen Datenstrukturen zu schreiben (kein sich ändernder Zustand). Dies reduziert den Bedarf an einem Debugger massiv. Sobald ich weiß, dass sich alle Komponenten so verhalten, wie ich es erwartet habe (unter besonderer Berücksichtigung der Arten von Dingen), ist das Verhalten in großem Maßstab selten ein Problem.
quelle
Wenn Sie Emacs / Slime / Swank verwenden, versuchen Sie dies bei der REPL:
Es gibt Ihnen keine vollständige Stapelverfolgung, wie Sie sie unter LISP erhalten würden, aber es ist gut zum Stöbern.
Dies ist die gute Arbeit von:
http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml
wie oben in einem Kommentar erwähnt.
quelle
Für IntelliJ gibt es ein exzellentes Clojure-Plugin namens Cursive . Unter anderem bietet es eine REPL, die Sie im Debug-Modus ausführen und Ihren Clojure-Code genau wie bei Java durchlaufen können.
Ich würde die Antwort von Peter Westmacott unterstützen, da meiner Erfahrung nach das Ausführen von Teilen meines Codes in der REPL die meiste Zeit eine ausreichende Form des Debuggens ist.
quelle
Leiningen
Error running 'ring server': Trampoline must be enabled for debugging
ring
oderlein
- vielleicht lohnt es sich, eine separate Frage zu stellen?Ab 2016 können Sie Debux verwenden , eine einfache Debugging-Bibliothek für Clojure / Script, die sowohl mit Ihrem Repl als auch mit der Konsole Ihres Browsers zusammenarbeitet. Sie können Makros in Ihren Code streuen
dbg
(debuggen) oderclog
(console.log) und auf einfache Weise die Ergebnisse einzelner Funktionen usw. beobachten, die auf Ihrer REPL und / oder Konsole gedruckt sind.Aus der Readme - Datei des Projekts :
quelle
Hugo Duncan und seine Mitarbeiter leisten weiterhin hervorragende Arbeit mit dem Ritz- Projekt. Ritz-nrepl ist ein nREPL-Server mit Debug-Funktionen. Sehen Sie sich Hugos Debugger in Clojure- Vorträgen auf der Clojure / Conj 2012 an, um sie in Aktion zu sehen. Im Video sind einige der Folien nicht lesbar, daher möchten Sie die Folien möglicherweise von hier aus anzeigen .
quelle
Verwenden Sie Spyscope, das ein benutzerdefiniertes Reader-Makro implementiert, sodass Ihr Debug-Code auch Produktionscode https://github.com/dgrnbrg/spyscope ist
quelle
Ich komme aus Java und bin mit Eclipse vertraut. Mir gefällt, was Counterclockwise (das Eclipse-Plugin für die Clojure-Entwicklung) zu bieten hat: http://doc.ccw-ide.org/documentation.html#_debug_clojure_code
quelle
Hier ist ein schönes Makro zum Debuggen komplizierter
let
Formulare:... und ein Aufsatz, der seine Verwendung erklärt .
quelle
Funktionsversion von def-let, die aus einem let eine Reihe von defs macht. Ein bisschen Kredit geht hierher
Verwendung: Muss den Inhalt mit einem Zitat zitieren, z
quelle