Ho copiato il seguente codice Ruby da Internet e ho apportato alcune modifiche, ma non funziona.
Cosa posso fare per eseguire il debug del programma da solo?
Ho copiato il seguente codice Ruby da Internet e ho apportato alcune modifiche, ma non funziona.
Cosa posso fare per eseguire il debug del programma da solo?
Risposte:
Installa tramite:
$ gem install pry
$ pry
Poi aggiungi:
require 'pry'; binding.pry
nel tuo programma.
Al pry
0.12.2 tuttavia, ci sono i comandi non navigazione quali next
, break
ecc Alcune altre gemme inoltre fornire questo, si veda ad esempio pry-byedebug
.
binding.pry
. Viene fornito anche con il completamento del colore, la ricerca della documentazione e la possibilità di modificare e ricaricare dinamicamente un metodo.
Pry
/ byebug
sono fantastici, ma non come il primo passo durante il debug. Nella maggior parte dei casi, sollevare un'eccezione con raise object.inspect
risolverà il problema più rapidamente dell'apertura di una sessione IRB. Consiglio di utilizzare i debugger della console solo una volta che soluzioni più semplici come la creazione di un'eccezione non sono in grado di risolvere il problema.
pry
? Non riuscivo a trovare come farlo; ed è quello che mi aspetto da un debugger.
In Ruby:
ruby -rdebug myscript.rb
poi,
b <line>
: inserire il punto di interruzione n(ext)
o s(tep)
ec(ontinue)
p(uts)
per la visualizzazione(come perl debug)
In Rails: avvia il server con
script/server --debugger
e aggiungi debugger
il codice.
-r debug
è spazzatura?
facets
requisiti gemma e non ho avuto successo. Per le app Rails antiche ruby-debug
è un po 'brutto, ma fa il lavoro.
Come raccomandato dalla ringhiera: usa la leva! Posso solo essere d'accordo su questo.
pry è un sostituto molto migliore di irb.
Devi aggiungere
require 'pry'
nel file sorgente e quindi inserire un punto di interruzione nel codice sorgente aggiungendo
binding.pry
nel punto in cui si desidera dare un'occhiata alle cose (è come innescare un punto di interruzione in un ambiente IDE classico)
Una volta che il programma ha colpito il
binding.pry
linea, verrai gettato direttamente nella riserva, con tutto il contesto del tuo programma a portata di mano, in modo da poter semplicemente esplorare tutto intorno, investigare tutti gli oggetti, cambiare stato e persino cambiare il codice al volo.
Credo che non sia possibile modificare il codice del metodo in cui ci si trova attualmente, quindi purtroppo non è possibile modificare la riga successiva da eseguire. Ma un buon codice rubino tende comunque ad essere una riga singola ;-)
Il debug aumentando le eccezioni è molto più semplice dello strabismo attraverso leprint
istruzioni di registro e, per la maggior parte dei bug, è generalmente molto più veloce dell'apertura di un debugger irb comepry
obyebug
. Questi strumenti non dovrebbero sempre essere il tuo primo passo.
Exception
allora e il .inspect
suo risultatoIl modo più veloce per eseguire il debug del codice Ruby (in particolare Rails) è raise
un'eccezione lungo il percorso di esecuzione del codice mentre si chiama .inspect
il metodo o l'oggetto (ad es. foo
):
raise foo.inspect
Nel codice sopra, raise
attiva un metodo Exception
che interrompe l'esecuzione del codice e restituisce un messaggio di errore che contiene convenientemente .inspect
informazioni sull'oggetto / metodo (ad es.foo
) sulla riga che si sta tentando di eseguire il debug.
Questa tecnica è utile per esaminare rapidamente un oggetto o un metodo ( ad esempio, è nil
? ) E per confermare immediatamente se una riga di codice viene persino eseguita in un determinato contesto.
byebug
opry
Solo dopo aver ottenuto informazioni sullo stato del flusso di esecuzione dei codici, è possibile passare a un debugger ruby gem irb come pry
o byebug
dove è possibile approfondire lo stato degli oggetti all'interno del percorso di esecuzione.
Quando si tenta di eseguire il debug di un problema, un buon consiglio è sempre: leggere il messaggio di errore! @ # $ Ing (RTFM)
Ciò significa leggere attentamente e completamente i messaggi di errore prima di agire in modo da capire cosa sta cercando di dirti. Quando esegui il debug, fai le seguenti domande mentali, in questo ordine , quando leggi un messaggio di errore:
nil
? ) Nella traccia dello stack presta particolare attenzione alle righe di codice che provengono dal tuo progetto (ad esempio le righe che iniziano con app/...
se stai usando Rails). Il 99% delle volte il problema riguarda il tuo codice.
Per illustrare perché l'interpretazione in questo ordine è importante ...
Esegui codice che a un certo punto viene eseguito come tale:
@foo = Foo.new
...
@foo.bar
e viene visualizzato un errore che indica:
undefined method "bar" for Nil:nilClass
I principianti vedono questo errore e pensano che il problema sia che il metodo nonbar
è definito . Non è. In questo errore la parte reale che conta è:
for Nil:nilClass
for Nil:nilClass
significa che @foo
è zero! @foo
non è una Foo
variabile di istanza! Hai un oggetto che è Nil
. Quando vedi questo errore, è semplicemente ruby che prova a dirti che il metodo bar
non esiste per gli oggetti della classe Nil
. (beh duh! dato che stiamo provando a usare un metodo per un oggetto della classe Foo
no Nil
).
Sfortunatamente, a causa di come viene scritto questo errore ( undefined method "bar" for Nil:nilClass
) è facile indurlo a pensare che questo errore abbia a che fare con l' bar
essere undefined
. Se non letto attentamente, questo errore fa sì che i principianti vadano erroneamente a scavare nei dettagli del bar
metodo Foo
, perdendo completamente la parte dell'errore che suggerisce che l'oggetto è della classe sbagliata (in questo caso: zero). È un errore che può essere facilmente evitato leggendo i messaggi di errore nella loro interezza.
Sommario:
Leggere sempre attentamente l' intero messaggio di errore prima di iniziare qualsiasi debug. Ciò significa: controllare sempre il codice categoria tipo di un oggetto in un messaggio di errore prima , poi i suoi metodi , prima di iniziare sleuthing in qualsiasi stacktrace o riga di codice in cui si pensa l'errore può essere che si verificano. Quei 5 secondi possono farti risparmiare 5 ore di frustrazione.
tl; dr: non strizzare gli occhi nei registri di stampa: solleva eccezioni o usa invece un debugger irb. Evita le tane del coniglio leggendo attentamente gli errori prima del debug.
Stampa le variabili quando possibile. (Si chiama debug printf) È possibile farlo eseguendo
STDERR.puts x.inspect
o
STDERR.puts "Variable x is #{x.inspect}"
Se si vuole fare questo più facile da digitare, quindi si consiglia di utilizzare l'exemplor gemma.
Attiva gli avvisi. Se stai correndo, ruby
eseguilo con l' -w
interruttore (ad es ruby -w script.rb
.). Se lo stai eseguendo da IRB e stai utilizzando una versione di ruby precedente alla 1.9.2, digita $VERBOSE = true
all'inizio della sessione. Se si scrive erroneamente una variabile di istanza, una volta attivati gli avvisi si otterrà
attenzione: variabile di istanza
@valeus
non inizializzata
Comprendi il concetto di un taglio binario (la seguente citazione è tratta da Practices of a Agile Developer )
Dividi lo spazio del problema a metà e vedi quale metà contiene il problema. Quindi dividi di nuovo quella metà a metà e ripeti.
Se hai successo con un taglio binario, potresti scoprire che esiste una sola riga che non fa ciò che ti aspetti che faccia. Per esempio
[1, 2, 3].include?([1,2])
dà un valore di false
, anche se pensi che sarebbe tornato true
. In tal caso, potresti voler consultare la documentazione. I siti Web per la documentazione includono ruby-doc.org o APIdock . In quest'ultimo caso, dovresti digitare include?
accanto alla lente d'ingrandimento vicino all'angolo in alto a destra, scegliere quello include?
che ha Array
sotto di essa (se non sai che classe [1, 2, 3]
è, digitare [1, 2, 3].class
irb) e potresti includere? (Array) , che descrive cosa fa.
Tuttavia, se la documentazione non aiuta, è più probabile che tu ottenga una buona risposta se puoi porre una domanda su come una riga specifica non sta facendo ciò che dovrebbe, piuttosto che perché un intero script non sta facendo cosa dovrebbe.
elimina tutte le cose
Benvenuti nel 2017 ^ _ ^
Bene, quindi se non ti opponi a provare un nuovo IDE puoi fare quanto segue gratuitamente .
launch.json
da utilizzare "cwd"
e e "program"
utilizzando il{workspaceRoot}
macro"showDebuggerOutput"
e impostalo sutrue
"debug.allowBreakpointsEverywhere": true
vscode
; questo non è lo stesso di Visual Studio . È gratuito, leggero e generalmente considerato positivamente.View->Extensions
.vscode
e lì dentro ci sarà un file chiamato launch.json
dove memorizzeremo alcune opzioni di configurazione.
launch.json
Contenuti
{
"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
(o Ctrl,) e scorreremo fino a raggiungere la Debug
sezione. Espandilo e cerca un campo chiamato "debug.allowBreakpointsEverywhere"
: seleziona quel campo e fai clic sulla piccola icona a forma di matita e impostalo su true
.Dopo aver fatto tutte quelle cose divertenti, dovresti essere in grado di impostare punti di interruzione e debug in un menu simile a questo per la metà del 2017 e un tema più scuro: con tutte le cose divertenti come il tuo stack di chiamate, il visualizzatore di variabili, ecc.
Il PITA più grande è 1) l'installazione dei pre-req e 2) ricordando di configurare il .vscode\launch.json
file. Solo il numero 2 dovrebbe aggiungere qualsiasi bagaglio a progetti futuri e puoi semplicemente copiare una configurazione abbastanza generica come quella sopra elencata. Probabilmente c'è una posizione di configurazione più generale, ma non lo so dalla cima della mia testa.
Consiglio vivamente questo video, al fine di scegliere lo strumento giusto al momento per eseguire il debug del nostro codice.
https://www.youtube.com/watch?v=GwgF8GcynV0
Personalmente, vorrei evidenziare due grandi argomenti in questo video.
Sono i miei due centesimi!
Tutte le altre risposte danno già quasi tutto ... Solo una piccola aggiunta.
Se vuoi un altro debugger simile a IDE (non CLI) e non hai paura di usare Vim come editor, suggerisco Vim Ruby Debugger plugin .
La sua documentazione è piuttosto semplice, quindi segui il link e vedi. In breve, ti consente di impostare il punto di interruzione nella riga corrente nell'editor, visualizzare le variabili locali in una finestra elegante in pausa, passare / entrare - quasi tutte le solite funzionalità di debugger.
Per me è stato abbastanza divertente utilizzare questo debugger vim per il debug di un'app Rails, anche se le ricche capacità di logger di Rails ne eliminano quasi la necessità.
Ho appena scoperto questo gioiello (trasforma Pry in un debugger per MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Installa con:
gem install pry-byebug
quindi usa esattamente come pry
, segna la linea che vuoi interrompere:
require 'pry'; binding.pry
A differenza della leva vaniglia, tuttavia, questo gioiello ha alcuni comandi di navigazione simili a GDB come next
, step
e 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
bandiera (avvisi)irb
è un ottimo punto di partenza. Prova a usare irb con piccoli pezzi discutibili. Adoro ruby-debug (ruby-debug19 per Ruby 1.9+) perché semplifica l'arresto del programma in esecuzione, l'esame delle variabili, il rilascio in irb, quindi continua l'esecuzione.
Per eseguire facilmente il debug dello script della shell Ruby, basta cambiare la sua prima riga da:
#!/usr/bin/env ruby
per:
#!/usr/bin/env ruby -rdebug
Quindi ogni volta che viene visualizzata la console di debugger, puoi scegliere:
c
per Continua (alla prossima eccezione, punto di interruzione o linea con: debugger
,n
per la riga successiva,w
/where
per visualizzare frame / stack di chiamate,l
per mostrare il codice corrente,cat
per mostrare punti di cattura.h
per ulteriore aiuto.Vedi anche: Debug con ruby-debug , scorciatoie da tastiera per gemma ruby-debug .
Se lo script si blocca e hai bisogno di un backtrace, prova a usare lldb
/ gdb
like:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
e quindi controlla il tuo processo in primo piano.
Sostituire lldb
con gdb
se funziona meglio. Prefisso con sudo
per eseguire il debug di processi non di proprietà.
A partire da Ruby 2.4.0, è più facile avviare una sessione REPL IRB nel mezzo di qualsiasi programma Ruby. Inserisci queste righe nel punto in cui vuoi eseguire il debug del programma:
require 'irb'
binding.irb
È possibile eseguire il codice Ruby e stampare le variabili locali. Digitare Ctrl + D o quit
per terminare il REPL e lasciare che il programma Ruby continui a funzionare.
Puoi anche usare puts
e p
stampare valori dal tuo programma mentre è in esecuzione.
Se si utilizza RubyMine , il debug degli script ruby è semplice e diretto.
Supponiamo di avere uno script Ruby hello_world.rb
Impostare un punto di interruzione alla riga 6 come di seguito.
Ora puoi semplicemente avviare il debugger per eseguire lo script:
Quindi quando l'esecuzione raggiunge un punto di interruzione, sarai in grado di ispezionare le variabili, ecc.
debug di printf
C'è sempre stata una controversia sulle tecniche di debug, ad alcune persone piace eseguire il debug con le dichiarazioni stampate, altre come scavare a fondo con un debugger.
Suggerirei di provare entrambi gli approcci.
In realtà uno dei vecchi uomini di Unix ha recentemente affermato che il debugging di printf è stato un modo più veloce di procedere per lui in alcuni punti.
Ma se sei nuovo in qualche posto di lavoro e hai bisogno di capire una grossa quantità di codice, è davvero utile spostarti dappertutto, mettendo alcuni punti di interruzione qua e là, andando avanti con esso come funziona.
Dovrebbe darti una certa comprensione di come è intessuto il codice.
Se non conosci il software di altre persone, potrebbe esserti di aiuto.
Scoprirai rapidamente se l'hanno organizzato in modo intelligente o se è solo un mucchio di merda.
Bene, ruby standard lib ha un debugger per console simile a gdb: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Non è necessario installare gemme extra. Gli script di Rails possono anche essere sottoposti a debug in questo modo.
per esempio
def say(word)
require 'debug'
puts word
end
La madre di tutti i debugger è una semplice schermata di stampa. Il più delle volte, probabilmente vuoi solo ispezionare alcuni oggetti semplici, un modo semplice e veloce è così:
@result = fetch_result
p "--------------------------"
p @result
Questo stamperà il contenuto di @result su STDOUT con una riga davanti per una facile identificazione.
Bonus se usi un framework con caricamento automatico / ricarica come Rails, non dovrai nemmeno riavviare la tua app. (A meno che il codice di cui si sta eseguendo il debug non venga ricaricato a causa di impostazioni specifiche del framework)
Trovo che questo funzioni per il 90% del caso d'uso per me. Puoi anche usare ruby-debug, ma lo trovo eccessivo per la maggior parte del tempo.
Esistono molti debugger con funzionalità diverse, in base alla quale fai la scelta. Le mie priorità erano soddisfatte con le mosse di leva che erano: