¿Cómo depuro scripts Ruby?


Copié el siguiente código Ruby de Internet e hice algunos cambios.

#insert code here

Pero no funciona!

Por favor ayuda. ¿Qué puedo hacer para depurar el programa yo solo?

Author: meagar, 2010-10-18

17 answers

Use Pry (GitHub ).

Instalar a través de:

$ gem install pry
$ pry

Luego agrega:

require 'pry'

En su programa.

 125
Author: horseyguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-01 17:04:19
  1. En Ruby:

    ruby -rdebug myscript.rb 
    

    Entonces

    • b <line>: poner punto de ruptura
    • y n(ext) o s(tep) y c(ontinue)
    • {[6] } para visualización

    (como perl debug)

  2. En Rails: Inicie el servidor con

    script/server --debugger
    

    Y añadir debugger en el código.

 107
Author: germanlinux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-01 04:47:00

Como barandilla recomendada: use pry! Sólo puedo estar de acuerdo en esto.

Pry es un repl mucho mejor que irb.

Necesitas agregar

require 'pry'

A su archivo fuente y luego inserte un punto de interrupción en su código fuente agregando

binding.pry

En el lugar donde quieres echar un vistazo a las cosas (esto es como activar un punto de interrupción en un entorno IDE clásico)

Una vez que el programa llega a la

binding.pry

Línea, usted será arrojado a la derecha en el pry repl, con todos los contexto de su programa al alcance de la mano, para que pueda simplemente explorar todo a su alrededor, investigar todos los objetos, cambiar el estado, e incluso cambiar el código sobre la marcha.

Creo que no puede cambiar el código del método en el que se encuentra actualmente, así que tristemente no puedes cambiar la siguiente línea para ser ejecutada. Pero el buen código ruby tiende a ser una sola línea de todos modos; -)

 51
Author: edx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-06 23:36:09

Depuración mediante el aumento de excepciones es mucho más fácil que entrecerrar los ojos a través de print instrucciones de registro, y para la mayoría de los errores, es generalmente mucho más rápido que abrir un depurador irb como pry o byebug. Esas herramientas no deberían ser tu primer paso.


Depurar Ruby / Rails rápidamente:

1. Método rápido: Levante un Exception entonces y .inspect su resultado

La forma más rápida de depurar código Ruby (especialmente Rails) es raise una excepción a lo largo de la ruta de ejecución de su código mientras llama a .inspect en el método u objeto (p.ej. foo):

raise foo.inspect

En el código anterior, raise desencadena una Exception que detiene la ejecución de su código, y devuelve un mensaje de error que convenientemente contiene .inspect información sobre el objeto/método (es decir, foo) en la línea que está tratando de depurar.

Esta técnica es útil para examinar rápidamente un objeto o método ( e. g. is it nil?) y para confirmar inmediatamente si una línea de código está siendo ejecutada dentro de un contexto dado.

2. Fallback: Utilice un depurador ruby IRB como byebug o pry

Solo después de tener información sobre el estado del flujo de ejecución de sus códigos debe considerar pasar a un depurador irb de gemas ruby como pry o byebug donde puede profundizar más en el estado de los objetos dentro de su ejecución camino.


Consejos Generales para principiantes

Cuando usted está tratando de depurar un problema, un buen consejo es siempre: ¡Lee El !@ # Message Mensaje de error de ing (RTFM)

Eso significa leer los mensajes de error cuidadosamente y completamente antes de actuar para que usted entienda lo que está tratando de decirle. Al depurar, haga las siguientes preguntas mentales, en este orden, al leer un error mensaje:

  1. Qué clase ¿hace referencia al error? (es decir, ¿tengo la clase de objeto correcta o es mi objeto nil?)
  2. Qué método ¿hace referencia al error? (es decir, es su tipo a en el método; ¿puedo llamar a este método en este tipo/clase de objeto?)
  3. Finalmente, usando lo que puedo inferir de mis dos últimas preguntas, lo que líneas de código ¿debería investigar? (recordar: la última línea de código en el seguimiento de la pila no es necesariamente donde se encuentra el problema.)

En el seguimiento de la pila, preste especial atención a las líneas de código que provienen de su proyecto (por ejemplo, las líneas que comienzan con app/... si está utilizando Rails). El 99% de las veces el problema es con su propio código.


Para ilustrar por qué interpretar en este orden es importante...

Por ejemplo, un mensaje de error de Ruby que confunde a muchos principiantes:

Usted ejecuta código que en algún momento se ejecuta como tal:

@foo = Foo.new

...

@foo.bar

Y obtienes un error que dice:{[47]]}

undefined method "bar" for Nil:nilClass

Los principiantes ven este error y piensan que el problema es que el método bar es indefinido. No lo es. En este error la parte real que importa es: {[47]]}

for Nil:nilClass

for Nil:nilClass significa que @foo es Nulo! @foo ¡no es una variable de instancia Foo! Tienes un objeto que es Nil. Cuando ves este error, es simplemente ruby intenta decirle que el método bar no existe para los objetos de la clase Nil. (bueno, duh! ya que estamos tratando de usar un método para un objeto de la clase Foo no Nil).

Desafortunadamente, debido a cómo se escribe este error (undefined method "bar" for Nil:nilClass) es fácil ser engañado pensando que este error tiene que ver con bar siendo undefined. Cuando no se lee con cuidado, este error hace que los principiantes se adentren erróneamente en los detalles del método bar en Foo, que falta por completo la parte del error que sugiere que el objeto es de la clase incorrecta (en este caso: nil). Es un error que se evita fácilmente leyendo mensajes de error en su totalidad.

Resumen:

Siempre con cuidado lea el mensaje de error completo antes de comenzar cualquier depuración. Eso significa: Siempre compruebe el clase tipo de un objeto en un mensaje de error primero , luego su métodos , antes de usted comienza a investigar en cualquier stacktrace o línea de código donde usted piensa que el error puede estar ocurriendo. Esos 5 segundos pueden ahorrarte 5 horas de frustración.

Tl; dr: No entrecerre los ojos en los registros de impresión: aumente las excepciones en su lugar. Evite agujeros de conejo leyendo los errores cuidadosamente antes de depurar.

 24
Author: Kelsey Hannan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-18 20:47:28
  1. Imprima las variables siempre que sea posible. (Esto se llama depuración de printf) Puede hacer esto ejecutando

    STDERR.puts x.inspect
    

    O

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

    Si desea que esto sea más fácil de escribir, entonces puede usar la gema exemplor.

  2. Encienda las advertencias. Si está ejecutando ruby, ejecútelo con el interruptor -w (por ejemplo, ruby -w script.rb). Si lo estás ejecutando desde irb, y estás usando una versión de ruby anterior a la 1.9.2, escribe $VERBOSE = true al inicio de tu sesion. Si escribe mal una variable de instancia, una vez que las advertencias estén activadas, obtendrá

    Advertencia: variable de instancia @valeus no inicializada

  3. Entender el concepto de un corte binario (la siguiente cita es de Prácticas de un Desarrollador Ágil)

    Divida el espacio del problema por la mitad, y vea qué mitad contiene el problema. Luego divida esa mitad por la mitad de nuevo, y repita.

  4. Si tienes éxito con un corte binario, puede encontrar que hay una sola línea que no hace lo que espera que haga. Por ejemplo

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

    Da un valor de false, aunque pensarías que devolvería true. En ese caso, es posible que desee mirar la documentación. Los sitios web para documentación incluyen ruby-doc.org , o APIdock. En este último caso, escribiría include? junto a la lupa cerca de la esquina superior derecha, elija el include? que tiene Array debajo de él (si ¿no sabes qué clase es [1, 2, 3], escribe [1, 2, 3].classen irb), y llegas a include? (Array) , que describe lo que hace.

    Sin embargo, si la documentación no ayuda, es más probable que obtenga una buena respuesta si puede hacer una pregunta sobre cómo una línea específica no está haciendo lo que debería, en lugar de por qué un script completo no está haciendo lo que debería.

 19
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-01 04:43:49

Todas las demás respuestas ya dan casi todo... Sólo una pequeña adición.

Si quieres más depurador IDE (no CLI) y no tienes miedo de usar Vim como editor, sugiero Vim Ruby Debugger plugin para ello.

Su documentación es bastante sencilla, así que siga el enlace y vea. En resumen, le permite establecer el punto de interrupción en la línea actual en el editor, ver las variables locales en la ventana ingeniosa en pausa, pasar por encima / en-casi todos los depuradores habituales función.

Para mí fue bastante agradable usar este depurador vim para depurar una aplicación Rails, aunque las ricas capacidades del registrador de Rails casi eliminan la necesidad de hacerlo.

 7
Author: NIA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 08:15:46
  1. Puede imprimir sus variables en el camino
  2. Encienda la bandera -w (advertencias)
  3. Utilice una herramienta como ruby-debug
 5
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-17 23:18:23

Recomiendo encarecidamente este video, con el fin de elegir la herramienta adecuada en este momento para depurar nuestro código.

Https://www.youtube.com/watch?v=GwgF8GcynV0

Personalmente, destacaría dos grandes temas en este video.

  • Pry es impresionante para los datos de depuración," pry es un explorador de datos " (sic)
  • El depurador parece ser mejor depurar paso a paso.
¡Esos son mis dos centavos!
 5
Author: DavidSilveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-17 23:41:05

Acabo de descubrir esta gema (convierte a Pry en un depurador para 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.
 5
Author: nurettin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-27 18:53:03

Para depurar fácilmente el script de Ruby shell, simplemente cambie su primera línea de:

#!/usr/bin/env ruby

A:

#!/usr/bin/env ruby -rdebug

Luego, cada vez que se muestre la consola del depurador, puede elegir:

  • c para Continuar (a la siguiente Excepción, punto de interrupción o línea con: debugger),
  • n para la siguiente línea,
  • w/where para mostrar la pila de frame / call,
  • l para Mostrar el código actual,
  • cat para mostrar los catchpoints.
  • h para más Ayudar.

Ver también: Depuración con ruby-debug, Atajos de teclas para ruby-debug gem .


En caso de que el script simplemente se cuelgue y necesite una traza inversa, intente usar lldb/gdb me gusta:

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

Y luego verifique el primer plano de su proceso.

Sustitúyase lldb por gdb si funciona mejor. Prefijo con sudo para depurar procesos no propios.

 5
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:33

borra todas las cosas

Bienvenido a 2017 ^ _ ^

Está bien, así que si no te opones a probar un nuevo IDE puedes hacer lo siguiente para free.

Instrucciones rápidas

  1. Instalar vscode
  2. Instale Ruby Dev Kit si aún no lo ha hecho
  3. Instalar extensiones Ruby, ruby-linter y ruby-rubocop para vscode
  4. Instale manualmente las gemas que rubyide / vscode-ruby especifique , si necesario
  5. Configure su launch.json para usar "cwd" y y "program" campos que utilizan la macro {workspaceRoot}
  6. Agregue un campo llamado "showDebuggerOutput" y póngalo en true
  7. Habilite puntos de interrupción en todas partes en sus preferencias de depuración como "debug.allowBreakpointsEverywhere": true

Instrucciones detalladas

  1. Descargar Visual Studio Code aka vscode; esto no es lo mismo que Visual Studio. Es gratis, ligero y generalmente considerado positivamente.
  2. Instala el Ruby Kit de desarrollo; debe seguir las instrucciones en su repositorio aquí: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. A continuación puede instalar extensiones a través de un navegador web, o dentro del IDE; esto es para dentro del IDE. Si elige el otro, puede ir aquí . Navegue a la parte de extensiones de vscode; puede hacer esto de un par de maneras, pero el método más a prueba de futuro probablemente será golpear F1 y escribir ext hasta que una opción llamada Extensions: Install Extensions esté disponible. Las alternativas son CtrlShiftx y desde la barra de menú superior, View->Extensions
  4. A continuación, vas a querer las siguientes extensiones; estas no son 100% necesarias, pero te dejaré decidir qué mantener después de haber cambiado algunas:
    • Ruby; extensión autor Peng Lv
    • ruby-rubocop; extensión autor misogi
    • ruby-linter; autor de la extensión Cody Hoover
  5. Dentro del directorio de su script ruby, vamos a hacer un directorio a través de la línea de comandos llamado .vscode y allí solo tendremos un archivo llamado launch.json donde vamos a almacenar algunas opciones de configuración.
    • launch.json contenido

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

  1. Siga las instrucciones de los autores de la extensión para las instalaciones manuales de gemas. Se encuentra aquí por ahora: https://github.com/rubyide/vscode-ruby#install-ruby-dependencies
  2. Probablemente querrá la capacidad de poner puntos de interrupción donde quiera; no tener esta opción habilitada puede causar confusión. Para ello, nos iremos a la barra de menú superior y seleccione File->Preferences->Settings (o Ctrl, ) y desplácese hasta llegar a la Debug sección. Expándelo y busque un campo llamado "debug.allowBreakpointsEverywhere" select seleccione ese campo y haga clic en el pequeño icono con aspecto de lápiz y configúrelo en true.

Después de hacer todas esas cosas divertidas, debería poder establecer puntos de interrupción y depurar en un menú similar a este para mediados de 2017 y un tema más oscuro:introduzca la descripción de la imagen aquí con todas las cosas divertidas como tu pila de llamadas, visor de variables, etc.

El PITA más grande es 1) instalar los pre-reqs y 2) Recordar configurar el archivo .vscode\launch.json. Solo #2 debería agregar cualquier equipaje a proyectos futuros, y puede copiar una configuración lo suficientemente genérica como la enumerada anteriormente. Hay probablemente una ubicación de configuración más general, pero no lo sé desde el principio de mi cabeza.

 5
Author: kayleeFrye_onDeck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-27 03:57:09

A partir de Ruby 2.4.0, es más fácil iniciar una sesión IRB REPL en medio de cualquier programa Ruby. Ponga estas líneas en el punto del programa que desea depurar:

require 'irb'
binding.irb

Puede ejecutar código Ruby e imprimir variables locales. Escriba Ctrl + D o quit para finalizar el REPL y dejar que el programa Ruby siga ejecutándose.

También puede usar puts y p para imprimir valores de su programa mientras se está ejecutando.

 4
Author: David Grayson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-12 03:07:46

Depuración de Printf

Siempre ha habido una controversia en torno a las técnicas de depuración, a algunas personas les gusta depurar mediante declaraciones de impresión, a otros les gusta profundizar con un depurador.

Te sugiero que pruebes ambos enfoques.

En realidad uno de los viejos Unix men dijo recientemente, esa depuración de printf fue una forma más rápida de hacerlo en algunos puntos.

Pero si eres nuevo en algún trabajo y necesitas entender una gran gota de código, entonces es realmente útil dar un paso a lo largo de allí, poniendo algunos puntos de interrupción aquí y allá, siguiendo con ello cómo funciona.

Debería darte un poco de comprensión de cómo se teje el código.

Si eres nuevo en algún software de otras personas, Podría ayudarte a pasar por ahí.

Descubrirás rápidamente si lo arreglaron de una manera inteligente, o si eso es sólo un montón de mierda.

 2
Author: edx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-06 23:55:45

La madre de todo el depurador es la pantalla de impresión antigua. La mayoría de las veces, probablemente solo desee inspeccionar algunos objetos simples, una forma rápida y fácil es como esta:

@result = fetch_result

p "--------------------------"
p @result

Esto imprimirá el contenido de @result a STDOUT con una línea al frente para una fácil identificación.

Bonus si utilizas un framework capaz de cargar / recargar automáticamente como Rails, ni siquiera necesitarás reiniciar tu app. (A menos que el código que está depurando no se vuelva a cargar debido a la configuración específica del marco)

Me parece que esto funciona para el 90% del caso de uso para mí. También puedes usar ruby-debug, pero me parece exagerado la mayor parte del tiempo.

 1
Author: Aaron Qian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 02:14:13

Bueno, ruby standard lib tiene un depurador de consola tipo gdb fácil de usar: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html No es necesario instalar ninguna joya adicional. Los scripts de Rails también se pueden depurar de esa manera.

Por ejemplo

def say(word)
  require 'debug'
  puts word
end
 1
Author: Forvater,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-13 08:24:30

Si está utilizando RubyMine, depurar scripts ruby es simple y directo.

Supongamos que tiene un script Ruby hello_world.rb

1. Establecer puntos de interrupción

Establezca un punto de interrupción en la línea 6 como se muestra a continuación.

introduzca la descripción de la imagen aquí

2. Iniciar depuración

Ahora puede iniciar el depurador para ejecutar el script:

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

3. Inspeccionar variables, etc.

Entonces, cuando la ejecución punto de interrupción, podrá inspeccionar variables, etc.

introduzca la descripción de la imagen aquí

Más información para su referencia

  1. Si desea usar RubyMine para realizar la depuración remota, puede hacerlo.
  2. Si desea usar RubyMine para depurar de forma remota rails que se ejecutan dentro de una docker, también es sencillo.
 1
Author: Yuci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-03 11:51:12

Hay muchos depuradores con diferentes características, en función de las cuales usted elige. Mis prioridades estaban satisfechas con movimientos de palanca que eran:

  • información rápidamente comprensible sobre cómo usar
  • pasos intuitivos (como entrar fácilmente en bloques)
  • "retroceder" (los movimientos de palanca satisfacen parcialmente la necesidad)
 1
Author: Dan Key,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-01 10:48:07