Legal, mas como você consegue o clojure para encontrar 'clojure.contrib.trace? Eu tenho o jar clojure-contrib no meu caminho de classe, mas o REPL dizuser=> (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
Você poderia estar digitando errado o clojure como fechamento ou isso é um erro de digitação no comentário? Você pode carregar outras bibliotecas clojure.contrib?
Se você estiver obtendo: "IllegalStateException não pode vincular dinamicamente var não dinâmico", consulte aqui: stackoverflow.com/questions/8875353/…
Cornelius
2
Também está funcionando na versão 1.5? Estou aprendendo Clojure com os koans clojure, mas ainda não consigo fazer o dotrace funcionar.
Nha
100
Eu tenho uma pequena macro de depuração que acho muito útil:
;;debugging parts of expressions(defmacro dbg[x] `(let[x# ~x](println "dbg:" '~x "=" x#) x#))
Você pode inseri-lo onde quiser assistir o que está acontecendo e quando:
@Zaz Eu concordo totalmente. Spyscope é incrível! Ainda melhor talvez do que um depurador. Certamente para digitar.
J Atkin
66
O CIDER do Emacs possui um depurador de origem que pode ser expresso por expressão dentro de um buffer Emacs e até injetar novos valores. Você pode ler tudo sobre isso aqui . Uma captura de tela demo:
Meu método favorito é uma aspersão liberal de printlns por todo o código ... É fácil ativá-los e desativá-los graças à #_macro do leitor (que faz com que o leitor leia da seguinte forma, depois finja que nunca o viu). Ou você pode usar uma macro expandindo para um corpo passado ou nildependendo do valor de alguma variável especial, digamos *debug*:
Então há algo que é atualmente incompatível com Swank-clojure 's REPL, mas é bom demais para não mencionar: debug-repl. Você pode usá-lo em um REPL independente, o que é fácil de obter, por exemplo, com Leiningen ( lein repl); e se você estiver iniciando seu programa a partir da linha de comando, ele trará o seu próprio REPL diretamente no seu terminal. A idéia é que você pode soltar a debug-replmacro em qualquer lugar que desejar e exibir a sua própria REPL quando a execução do programa atingir esse ponto, com todos os locais no escopo etc. Alguns links relevantes: O Clojure debug-repl , o Clojure debug -repl truques , que tal um depurador-repl (no grupo Clojure Google), depurador-repl em Clojars .
O swank-clojure faz um trabalho adequado para tornar o depurador interno do SLIME útil ao trabalhar com o código Clojure - observe como os bits irrelevantes do stacktrace ficam acinzentados, para que seja fácil encontrar o problema real no código que está sendo depurado. Um aspecto a ter em mente é que funções anônimas sem "tags de nome" aparecem no rastreamento de pilha com basicamente nenhuma informação útil anexada a elas; Quando uma "tag de nome" é adicionada, ela aparece no rastreamento de pilha e tudo está bem novamente:
(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)
^^^
Na verdade, há uma versão do debug-repl que funciona com Swank agora: hugoduncan.org/post/2010/... (Alerta de spoiler: é incrível)
1
Certo, e é bom ter um link aqui, obrigado! Concordou em incrível. :-)
Michał Marczyk
Se esse é o seu estilo, você pode gostar da biblioteca de debux mencionada em uma resposta subsequente. github.com/philoskim/debux
Mallory-Erik
@ Mallory-Erik Obrigado, vou dar uma olhada!
Michał Marczyk
37
Você também pode inserir código para se inserir em um REPL com todas as ligações locais, usando o de Alex Osbornedebug-repl :
(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))))
Em seguida, para usá-lo, insira-o onde quiser que a repl seja iniciada:
(defn my-function [a b c](let[d (some-calc)](debug-repl)))
Eu colo isso no meu user.clj para que fique disponível em todas as sessões do REPL.
"melhores maneiras de depurar o código Clojure, enquanto usa o repl"
Campo ligeiramente esquerdo, mas 'usando o próprio REPL'.
Escrevo o hobby de Clojure há mais de um ano e não sinto grande necessidade de ferramentas de depuração. Se você mantiver suas funções pequenas e executar cada uma delas com as entradas esperadas no REPL e observar os resultados, será possível ter uma imagem bastante clara de como seu código está se comportando.
Acho que um depurador é mais útil para observar STATE em um aplicativo em execução. O Clojure torna fácil (e divertido!) Escrever em um estilo funcional com estruturas de dados imutáveis (sem alteração de estado). Isso reduz enormemente a necessidade de um depurador. Quando eu sei que todos os componentes se comportam como eu esperava (prestando atenção especial aos tipos de coisas), o comportamento em larga escala raramente é um problema.
Para o IntelliJ, existe um excelente plugin Clojure chamado Cursive . Entre outras coisas, ele fornece um REPL que você pode executar no modo de depuração e percorrer seu código Clojure como faria para, por exemplo, Java.
Eu preferiria a resposta de Peter Westmacott, embora na minha experiência apenas executar partes do meu código no REPL seja, na maioria das vezes, uma forma suficiente de depuração.
Mas como depurar Leiningen, mostra:Error running 'ring server': Trampoline must be enabled for debugging
Gank
Isso parece específico ringou leintalvez valha a pena postar uma pergunta separada?
achou
6
A partir de 2016, você poderá usar o Debux , uma biblioteca de depuração simples para Clojure / Script que funciona em conjunto com seu repl e com o console do navegador. Você pode polvilhar dbg(depurar) ou clog(console.log) macros no seu código e observar facilmente os resultados de funções individuais, etc., impressas no seu REPL e / ou console.
Este é um exemplo simples. A macro dbg imprime um formulário original e imprime o valor avaliado na janela REPL. Em seguida, ele retorna o valor sem interferir na execução do código.
Hugo Duncan e colaboradores continuam fazendo um trabalho incrível com o projeto ritz . O Ritz-nrepl é um servidor nREPL com recursos de depuração. Assista a Debuggers de Hugo em Clojure conversando no Clojure / Conj 2012 para vê-lo em ação. No vídeo, alguns dos slides não são legíveis, portanto, você pode querer vê-los daqui .
Use o spyscope que implementa uma macro de leitor personalizada para que seu código de depuração também seja código de produção
https://github.com/dgrnbrg/spyscope
Respostas:
Há também o dotrace, que permite observar as entradas e saídas das funções selecionadas.
produz a saída:
No Clojure 1.4,
dotrace
mudou:Você precisa da dependência:
E você precisa adicionar a dinâmica ^: à definição da função
Então Bob é mais uma vez seu tio:
fonte
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)
Eu tenho uma pequena macro de depuração que acho muito útil:
Você pode inseri-lo onde quiser assistir o que está acontecendo e quando:
fonte
clojure.tools.trace/trace
.O CIDER do Emacs possui um depurador de origem que pode ser expresso por expressão dentro de um buffer Emacs e até injetar novos valores. Você pode ler tudo sobre isso aqui . Uma captura de tela demo:
fonte
Meu método favorito é uma aspersão liberal de
println
s por todo o código ... É fácil ativá-los e desativá-los graças à#_
macro do leitor (que faz com que o leitor leia da seguinte forma, depois finja que nunca o viu). Ou você pode usar uma macro expandindo para um corpo passado ounil
dependendo do valor de alguma variável especial, digamos*debug*
:Com um
(def *debug* false)
, isso será expandido paranil
. Comtrue
, ele será expandido parabody
envolto em umdo
.A resposta aceita para esta pergunta do SO: Cloneure Idiomatic para relatórios de progresso? é muito útil ao depurar operações de sequência.
Então há algo que é atualmente incompatível com Swank-clojure 's REPL, mas é bom demais para não mencionar:
debug-repl
. Você pode usá-lo em um REPL independente, o que é fácil de obter, por exemplo, com Leiningen (lein repl
); e se você estiver iniciando seu programa a partir da linha de comando, ele trará o seu próprio REPL diretamente no seu terminal. A idéia é que você pode soltar adebug-repl
macro em qualquer lugar que desejar e exibir a sua própria REPL quando a execução do programa atingir esse ponto, com todos os locais no escopo etc. Alguns links relevantes: O Clojure debug-repl , o Clojure debug -repl truques , que tal um depurador-repl (no grupo Clojure Google), depurador-repl em Clojars .O swank-clojure faz um trabalho adequado para tornar o depurador interno do SLIME útil ao trabalhar com o código Clojure - observe como os bits irrelevantes do stacktrace ficam acinzentados, para que seja fácil encontrar o problema real no código que está sendo depurado. Um aspecto a ter em mente é que funções anônimas sem "tags de nome" aparecem no rastreamento de pilha com basicamente nenhuma informação útil anexada a elas; Quando uma "tag de nome" é adicionada, ela aparece no rastreamento de pilha e tudo está bem novamente:
fonte
Você também pode inserir código para se inserir em um REPL com todas as ligações locais, usando o de Alex Osborne
debug-repl
:Em seguida, para usá-lo, insira-o onde quiser que a repl seja iniciada:
Eu colo isso no meu user.clj para que fique disponível em todas as sessões do REPL.
fonte
"melhores maneiras de depurar o código Clojure, enquanto usa o repl"
Campo ligeiramente esquerdo, mas 'usando o próprio REPL'.
Escrevo o hobby de Clojure há mais de um ano e não sinto grande necessidade de ferramentas de depuração. Se você mantiver suas funções pequenas e executar cada uma delas com as entradas esperadas no REPL e observar os resultados, será possível ter uma imagem bastante clara de como seu código está se comportando.
Acho que um depurador é mais útil para observar STATE em um aplicativo em execução. O Clojure torna fácil (e divertido!) Escrever em um estilo funcional com estruturas de dados imutáveis (sem alteração de estado). Isso reduz enormemente a necessidade de um depurador. Quando eu sei que todos os componentes se comportam como eu esperava (prestando atenção especial aos tipos de coisas), o comportamento em larga escala raramente é um problema.
fonte
Se você usa o emacs / slime / swank, tente isso no REPL:
Ele não fornece um rastreamento completo da pilha como você obteria no LISP, mas é bom para bisbilhotar.
Este é o bom trabalho de:
http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml
como foi mencionado em um comentário acima.
fonte
Para o IntelliJ, existe um excelente plugin Clojure chamado Cursive . Entre outras coisas, ele fornece um REPL que você pode executar no modo de depuração e percorrer seu código Clojure como faria para, por exemplo, Java.
Eu preferiria a resposta de Peter Westmacott, embora na minha experiência apenas executar partes do meu código no REPL seja, na maioria das vezes, uma forma suficiente de depuração.
fonte
Leiningen
, mostra:Error running 'ring server': Trampoline must be enabled for debugging
ring
oulein
talvez valha a pena postar uma pergunta separada?A partir de 2016, você poderá usar o Debux , uma biblioteca de depuração simples para Clojure / Script que funciona em conjunto com seu repl e com o console do navegador. Você pode polvilhar
dbg
(depurar) ouclog
(console.log) macros no seu código e observar facilmente os resultados de funções individuais, etc., impressas no seu REPL e / ou console.No Leiame do projeto :
fonte
Hugo Duncan e colaboradores continuam fazendo um trabalho incrível com o projeto ritz . O Ritz-nrepl é um servidor nREPL com recursos de depuração. Assista a Debuggers de Hugo em Clojure conversando no Clojure / Conj 2012 para vê-lo em ação. No vídeo, alguns dos slides não são legíveis, portanto, você pode querer vê-los daqui .
fonte
Use o spyscope que implementa uma macro de leitor personalizada para que seu código de depuração também seja código de produção https://github.com/dgrnbrg/spyscope
fonte
Vindo de Java e familiarizado com o Eclipse, gosto do que Counterclockwise (o plug-in do Eclipse para desenvolvimento do Clojure) tem a oferecer: http://doc.ccw-ide.org/documentation.html#_debug_clojure_code
fonte
Aqui está uma boa macro para depurar
let
formulários complicados :... e um ensaio explicando seu uso .
fonte
Versão da função def-let, que transforma um let em uma série de defs. Algum crédito vai para aqui
Uso: precisa citar o conteúdo com uma cotação, por exemplo
fonte