Come faccio a eseguire il debug degli script Ruby?

Ho copiato il seguente codice Ruby da Internet e ho apportato alcune modifiche.

#insert code here 

Ma non funziona!

Per favore aiuto. Cosa posso fare per eseguire il debug del programma da solo?

Usa Pry ( GitHub ).

Installa tramite:

 $ gem install pry $ pry 

Poi aggiungi:

 require 'pry' 

nel tuo programma.

  1. In Ruby:

     ruby -rdebug myscript.rb 

    poi,

    • b : inserire break-point
    • e n(ext) o s(tep) c(ontinue)
    • p(uts) per la visualizzazione

    (come perl debug)

  2. In Rails: avvia il server con

     script/server --debugger 

    e aggiungi il debugger nel codice.

Raccomandato come balaustra: usa la leva! Posso solo essere d’accordo su questo.

pry è un sostituto molto migliore di irb.

Devi aggiungere

 require 'pry' 

al tuo file sorgente e quindi inserisci un breakpoint nel tuo codice sorgente aggiungendo

 binding.pry 

nel luogo in cui si desidera dare un’occhiata alle cose (questo è come triggersre un punto di interruzione in un ambiente IDE classico)

Una volta che il tuo programma ha colpito il

 binding.pry 

linea, sarai gettato direttamente nel sostituto della leva, con tutto il contesto del tuo programma a portata di mano, in modo che tu possa semplicemente esplorare tutto intorno, investigare su tutti gli oggetti, cambiare stato, e persino cambiare il codice al volo.

Credo che non sia ansible modificare il codice del metodo in cui ci si trova attualmente, quindi non si può purtroppo modificare la riga successiva da eseguire. Ma il buon codice ruby tende ad essere una sola riga comunque 😉

Il debugging sollevando eccezioni è molto più semplice dello strizzare gli occhi attraverso print istruzioni del registro di print e, per la maggior parte degli errori, è generalmente molto più veloce dell’apertura di un debugger irb come pry o byebug . Questi strumenti non dovrebbero essere il tuo primo passo.


Eseguire il debug di Ruby / Rails rapidamente:

1. Metodo veloce: solleva .inspect e quindi verifica il suo risultato

Il modo più veloce per eseguire il debug del codice Ruby (in particolare Rails) consiste nel raise un’eccezione lungo il percorso di esecuzione del codice durante la chiamata a .inspect sul metodo o sull’object (ad es. foo ):

 raise foo.inspect 

Nel codice precedente, raise innesca Exception che interrompe l’esecuzione del codice e restituisce un messaggio di errore che contiene convenientemente informazioni .inspect sull’object / metodo (cioè foo ) sulla riga che si sta tentando di eseguire il debug.

Questa tecnica è utile per esaminare rapidamente un object o un metodo ( ad esempio è nil ? ) E per confermare immediatamente se una linea di codice viene addirittura eseguita in un dato contesto.

2. Fallback: usa un debugger IRB ruby come byebug o pry

Solo dopo aver ricevuto informazioni sullo stato del stream di esecuzione dei codici, dovresti prendere in considerazione la possibilità di passare a un debugger di ruby ​​gem irb come pry o byebug cui è ansible approfondire lo stato degli oggetti all’interno del percorso di esecuzione.


Consigli generali per principianti

Quando si tenta di eseguire il debug di un problema, un buon consiglio è sempre: leggere il messaggio di errore! @ # $ Errore (RTFM)

Ciò significa leggere attentamente i messaggi di errore prima di agire in modo che tu capisca cosa sta cercando di dirti. Quando esegui il debug, poni le seguenti domande mentali, in questo ordine , durante la lettura di un messaggio di errore:

  1. Quale class fa riferimento all’errore? (cioè ho la class dell’object corretta o il mio object è nil ? )
  2. Quale metodo fa riferimento l’errore? (cioè è il loro un tipo nel metodo, posso chiamare questo metodo su questo tipo / class di object? )
  3. Infine, usando ciò che posso dedurre dalle mie ultime due domande, quali linee di codice dovrei investigare? (ricorda: l’ultima riga di codice nella traccia dello stack non è necessariamente dove si trova il problema).

Nella traccia dello stack prestate particolare attenzione alle righe di codice che provengono dal vostro progetto (es. Le righe che iniziano con app/... se state usando Rails). Il 99% delle volte il problema è con il tuo codice.


Per illustrare perché interpretare in questo ordine è importante …

Ad esempio un messaggio di errore Ruby che confonde molti principianti:

Esegui codice che ad un certo punto viene eseguito come tale:

 @foo = Foo.new ... @foo.bar 

e ottieni un errore che afferma:

undefined method "bar" for Nil:nilClass

I principianti vedono questo errore e pensano che il problema sia che la bar del metodo non è definita . Non è. In questo errore la parte reale che conta è:

for Nil:nilClass

for Nil:nilClass significa che @foo è Nil! @foo non è una variabile di istanza di Foo ! Hai un object che è Nil . Quando vedi questo errore, è semplicemente ruby cercando di dirti che la bar del metodo non esiste per oggetti della class Nil . (beh, perché stiamo cercando di usare un metodo per un object della class Foo not Nil ).

Sfortunatamente, a causa di come viene scritto questo errore ( undefined method "bar" for Nil:nilClass ) è facile essere indotti a pensare che questo errore abbia a che fare con la bar undefined . Quando non viene letto attentamente, questo errore induce i principianti a scavare erroneamente nei dettagli del metodo bar su Foo , mancando completamente la parte dell’errore che suggerisce che l’object è della class sbagliata (in questo caso: nil). È un errore che è 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: verifica sempre prima il tipo di class di un object in un messaggio di errore, quindi i suoi metodi , prima di iniziare a investigare su uno stacktrace o una linea di codice dove pensi che possa essersi verificato l’errore. Quei 5 secondi possono farti risparmiare 5 ore di frustrazione.

tl; dr: Non strizzare gli occhi ai registri di stampa: alza invece le eccezioni. Evita buchi di rabbitmq leggendo gli errori attentamente prima di eseguire il debug.

  1. Stampa le variabili quando ansible. (Questo è chiamato debugging di printf) Puoi farlo eseguendo

     STDERR.puts x.inspect 

    o

     STDERR.puts "Variable x is #{x.inspect}" 

    Se si desidera semplificare la digitazione, è ansible utilizzare la gem exemplor .

  2. Attiva gli avvisi. Se stai ruby -w script.rb con l’ -w (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 esegui un’errore di ortografia su una variabile di istanza, una volta che gli avvisi sono attivi, otterrai

    warning: istanza variabile @valeus non inizializzata

  3. Comprendere il concetto di un chop binario (la seguente citazione proviene da Practices of an Agile Developer )

    Dividi lo spazio del problema a metà e vedi quale metà contiene il problema. Quindi dividi nuovamente metà a metà e ripeti.

  4. Se hai successo con un chop binario, potresti scoprire che c’è una singola linea che non fa ciò che ti aspetti che faccia. Per esempio

     [1, 2, 3].include?([1,2]) 

    dà un valore di false , anche se penseresti 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, digiteresti include? accanto alla lente d’ingrandimento vicino all’angolo in alto a destra, scegli l’ include? che ha Array sotto di esso (se non sai che class [1, 2, 3] è, scrivi [1, 2, 3].class in irb), e arrivi ad includere? (Matrice) , che descrive cosa fa.

    Tuttavia, se la documentazione non aiuta, è più probabile che tu ottenga una buona risposta se puoi fare una domanda su come una linea specifica non sta facendo ciò che dovrebbe, piuttosto che sul perché un intero script non sta facendo cosa dovrebbe.

Tutte le altre risposte danno già quasi tutto … Solo una piccola aggiunta.

Se vuoi qualche altro debugger IDE-like (non-CLI) e non hai paura di usare Vim come editor, ti suggerisco il plugin Vim Ruby Debugger .

La sua documentazione è piuttosto semplice, quindi segui il link e guarda. In breve, ti consente di impostare il punto di interruzione sulla riga corrente nell’editor, visualizzare le variabili locali in una bella finestra in pausa, passare sopra / su – quasi tutte le normali funzioni di debugger.

Per me è stato piuttosto divertente usare questo debugger di vim per il debug di un’app Rails, sebbene le ricche funzionalità di logger di Rails ne eliminassero quasi la necessità.

  1. Puoi stampare le tue variabili lungo la strada
  2. Attiva il flag -w (warnings)
  3. Utilizzare uno strumento come Ruby-Debug

Consiglio vivamente questo video, al fine di scegliere lo strumento adatto 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.

  • Pry è fantastico per i dati di debug, “leva è un esploratore di dati” (sic)
  • Debugger sembra essere meglio eseguire il debug passo dopo passo.

Sono i miei due centesimi!

Ho appena scoperto questo gioiello (trasforma Pry in un debugger per MRI Ruby 2.0+)

https://github.com/deivid-rodriguez/pry-byebug

 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. 

Per eseguire facilmente il debug dello script della shell Ruby, basta modificare la prima riga da:

 #!/usr/bin/env ruby 

a:

 #!/usr/bin/env ruby -rdebug 

Quindi, ogni volta che viene mostrata la console del debugger, puoi scegliere:

  • c per Continua (fino alla prossima eccezione, breakpoint o linea con: debugger ),
  • n per la riga successiva,
  • w / where to Visualizza frame / stack di chiamate,
  • l per mostrare il codice corrente,
  • cat per mostrare i punti di cattura.
  • h per ulteriore aiuto.

Vedi anche: Debug con ruby-debug , scorciatoie da tastiera per ruby-debug gem .


Nel caso in cui lo script si blocchi e hai bisogno di un backtrace, prova ad usare lldb / gdb come:

 echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby) 

e quindi controlla il processo in primo piano.

Sostituisci lldb con gdb se funziona meglio. Prefisso con sudo per eseguire il debug del processo non di proprietà.

cancella tutte le cose

Benvenuto nel 2017 ^ _ ^

Ok, quindi se non ti opponi a provare un nuovo IDE puoi fare quanto segue gratuitamente .

Istruzioni rapide

  1. Installa vscode
  2. Installa Ruby Dev Kit se non lo hai già fatto
  3. Installare estensioni Ruby, ruby-linter e ruby-rubocop per vscode
  4. Installa manualmente tutte le gemme che rubyide / vscode-ruby specifica , se necessario
  5. Configura il tuo launch.json per usare i "cwd" e "program" usando la macro {workspaceRoot}
  6. Aggiungi un campo chiamato "showDebuggerOutput" e "showDebuggerOutput" su true
  7. Abilita i breakpoint ovunque nelle preferenze di Debug come "debug.allowBreakpointsEverywhere": true

Istruzioni dettagliate

  1. Scarica il codice di Visual Studio aka vscode ; questo non è lo stesso di Visual Studio . È gratuito, leggero e generalmente considerato positivamente.
  2. Installa il kit Ruby Dev; dovresti seguire le istruzioni al loro repo qui: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. Successivamente è ansible installare le estensioni tramite un browser Web o all’interno dell’IDE; questo è per dentro l’IDE. Se scegli l’altro, puoi andare qui . Passare alla parte Estensioni di vscode; puoi farlo in un paio di modi, ma il metodo più a prova di futuro probabilmente colpirà F1 , e digitando e x t fino a quando non sarà disponibile un’opzione chiamata Estensioni: Installa estensioni . Le alternative sono Ctrl Shift x e dalla barra dei menu in alto, View->Extensions
  4. Quindi vorrai le seguenti estensioni; questi non sono necessari al 100%, ma ti permetterò di decidere cosa tenere dopo aver aggiustato alcuni:
    • Rubino; autore di estensione Peng Lv
    • ruby rubocop; estensione autore misogi
    • ruby Linter; autore di estensioni Cody Hoover
  5. All’interno della directory del tuo script ruby, .vscode una directory tramite la riga di comando chiamata .vscode e lì ci sarà solo un file chiamato launch.json dove andremo a memorizzare alcune opzioni di configurazione.
    • contenuti launch.json

{ "version": "0.2.0", "configurations": [ { "name": "Debug Local File", "type":"Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "{workspaceRoot}/../script_name.rb", "args": [], "showDebuggerOutput": true } ] }

  1. Segui le istruzioni degli autori di estensioni per le installazioni gem manuale. Si trova qui per ora: https://github.com/rubyide/vscode-ruby#install-ruby-dependencies
  2. Probabilmente vorrai la possibilità di inserire punti di interruzione dove preferisci; non avere questa opzione abilitata può causare confusione. Per fare questo, andremo alla barra dei menu in alto e selezionare File->Preferences->Settings (o Ctrl , ) e scorrere fino a raggiungere la sezione Debug . "debug.allowBreakpointsEverywhere" e cerca un campo chiamato "debug.allowBreakpointsEverywhere" : seleziona quel campo e fai clic sull’icona a forma di matita e "debug.allowBreakpointsEverywhere" su true .

Dopo aver fatto tutte queste cose divertenti, dovresti essere in grado di impostare i breakpoint e il debug in un menu simile a questo per la metà del 2017 e un tema più scuro: inserisci la descrizione dell'immagine qui con tutte le cose divertenti come lo stack di chiamate, il visualizzatore di variabili, ecc.

Il più grande PITA è 1) l’installazione dei pre-req e 2) Ricordando di configurare il file .vscode\launch.json . Solo # 2 dovrebbe aggiungere qualsiasi bagaglio ai progetti futuri, e puoi semplicemente copiare una configurazione abbastanza generica come quella sopra elencata. Probabilmente c’è una posizione di configurazione più generale, ma non so in cima alla mia testa.

A partire da Ruby 2.4.0, è più semplice avviare una sessione REB IRB nel mezzo di qualsiasi programma Ruby. Metti queste righe nel punto del programma che vuoi eseguire il debug:

 require 'irb' binding.irb 

È ansible eseguire il codice Ruby e stampare le variabili locali. Premi Ctrl + D o quit per terminare REPL e lascia che il programma Ruby continui a funzionare.

Puoi anche usare puts e p per stampare i valori dal tuo programma mentre è in esecuzione.

debug di printf

C’è sempre stata una controversia sulle tecniche di debugging, ad alcune persone piace fare il debug con le dichiarazioni di stampa, altre come scavare in profondità con un debugger.

Ti suggerirei di provare entrambi gli approcci.

In realtà uno dei vecchi uomini di Unix ha recentemente affermato che il debugging di printf era un modo più veloce per andare da lui in alcuni punti.

Ma se sei nuovo in un determinato lavoro e hai bisogno di capire una grande quantità di codice, allora è davvero utile passare da una parte all’altra, mettendo qualche punto di interruzione qua e là, procedendo con esso come funziona.

Dovrebbe darti un po ‘di comprensione del modo in cui il codice è intrecciato.

Se sei nuovo di un software di altri popoli, potrebbe aiutarti a passare da lì.

Scoprirai presto se l’hanno organizzato in modo intelligente, o se è solo un mucchio di merda.

La madre di tutti i debugger è semplicemente vecchio schermo di stampa. Il più delle volte, probabilmente vuoi solo ispezionare alcuni oggetti semplici, un modo facile e veloce è come questo:

 @result = fetch_result p "--------------------------" p @result 

Questo stamperà il contenuto di @result su STDOUT con una linea frontale per una facile identificazione.

Bonus se utilizzi un framework di caricamento automatico / ricarica come Rails, non avrai nemmeno bisogno di riavviare la tua app. (A meno che il codice che si sta eseguendo il debug non venga ricaricato a causa di impostazioni specifiche del framework)

Trovo che questo funzioni per il 90% del caso di utilizzo per me. Puoi anche usare ruby-debug, ma lo trovo eccessivo per la maggior parte del tempo.

Bene, la lib di Ruby standard ha un debugger per console simile a gdb facile da usare: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Non è necessario installare gemme extra. Anche gli script di Rails possono essere debellati in questo modo.

per esempio

 def say(word) require 'debug' puts word end 

Se si utilizza RubyMine , il debug degli script ruby ​​è semplice e diretto.

Supponi di avere uno script di Ruby hello_world.rb

1. Impostare i punti di interruzione

Impostare un punto di interruzione alla riga 6 come di seguito.

inserisci la descrizione dell'immagine qui

2. Avvia il debug

Ora puoi solo avviare il debugger per eseguire lo script:

inserisci la descrizione dell'immagine qui

inserisci la descrizione dell'immagine qui

3. Ispezionare le variabili, ecc.

Quindi, quando l’esecuzione raggiunge un punto di interruzione, sarai in grado di ispezionare le variabili, ecc.

inserisci la descrizione dell'immagine qui

Ulteriori informazioni per il vostro riferimento

  1. Se si desidera utilizzare RubyMine per eseguire il debug remoto , è ansible farlo.
  2. Se si desidera utilizzare RubyMine su binari di debug remoto in esecuzione all’interno di una finestra mobile , è anche semplice.

Esistono molti debugger con caratteristiche diverse, in base alle quali si effettua una scelta. Le mie priorità erano soddisfatte con le mosse che erano:

  • informazioni rapidamente comprensibili su come utilizzare
  • passaggi intuitivi (come un facile passaggio nei blocchi)
  • “fare un passo indietro” (le manovre di leva in parte soddisfano il bisogno)