Copié el siguiente código Ruby de Internet e hice algunos cambios pero no funciona.
¿Qué puedo hacer para depurar el programa yo solo?
Copié el siguiente código Ruby de Internet e hice algunos cambios pero no funciona.
¿Qué puedo hacer para depurar el programa yo solo?
Respuestas:
Instalar a través de:
$ gem install pry
$ pry
Luego añade:
require 'pry'; binding.pry
en su programa
A partir de pry
0.12.2 sin embargo, existen comandos no de navegación tales como next
, break
, etc. Algunas otras gemas, además, proporcionar esto, véase por ejemplo pry-byedebug
.
binding.pry
. También viene con finalización de color, búsqueda de documentación y posibilidad de editar y recargar dinámicamente un método ..
Pry
/ byebug
son geniales, pero no como su primer paso al depurar. En la mayoría de los casos, generar una excepción raise object.inspect
resolverá su problema más rápido que abrir una sesión irb. Recomiendo usar solo los depuradores de consola una vez más, las soluciones simples, como generar una excepción, no pueden resolver su problema.
pry
? No pude encontrar cómo hacerlo; y eso es lo que espero de un depurador.
En rubí:
ruby -rdebug myscript.rb
luego,
b <line>
: poner punto de quiebre n(ext)
o s(tep)
yc(ontinue)
p(uts)
para mostrar(como depuración perl)
En Rails: inicie el servidor con
script/server --debugger
y agregue debugger
el código.
-r debug
es basura?
facets
los requisitos de gemas, y no tuve éxito. Para las aplicaciones antiguas de Rails ruby-debug
es un poco desagradable, pero hace el trabajo.
Como la barandilla recomendada: ¡usa la palanca! Solo puedo estar de acuerdo en esto.
Pry es una respuesta 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 desea ver las cosas (esto es como activar un punto de interrupción en un entorno IDE clásico)
Una vez que su programa llegue al
binding.pry
línea, se lo arrojará directamente a la respuesta de palanca, con todo el contexto de su programa al alcance de la mano, para que pueda explorar todo, 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, por lo que lamentablemente no puede cambiar la siguiente línea que se ejecutará. Pero un buen código ruby tiende a ser una sola línea de todos modos ;-)
La depuración mediante excepciones es mucho más fácil que entrecerrar los ojos a través de lasprint
declaraciones de registro, y para la mayoría de los errores, generalmente es mucho más rápido que abrir un depurador irb comopry
obyebug
. Esas herramientas no siempre deberían ser su primer paso.
Exception
entonces y .inspect
su resultadoLa forma más rápida de depurar el código Ruby (especialmente Rails) es raise
una excepción a lo largo de la ruta de ejecución de su código al invocar .inspect
el método u objeto (por ejemplo foo
):
raise foo.inspect
En el código anterior, raise
activa un Exception
que detiene la ejecución de su código y devuelve un mensaje de error que contiene convenientemente .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 ( por ejemplo, nil
¿ lo es ? ) Y para confirmar de inmediato si una línea de código se está ejecutando en un contexto determinado.
byebug
opry
Solo después de tener información sobre el estado del flujo de ejecución de sus códigos, debería considerar pasar a un depurador de ruby gem irb como pry
o byebug
donde puede profundizar en el estado de los objetos dentro de su ruta de ejecución.
Cuando intenta depurar un problema, un buen consejo es siempre: Leer el mensaje de error! @ # $ Ing (RTFM)
Eso significa leer los mensajes de error cuidadosa y completamente antes de actuar para que comprenda lo que está tratando de decirle. Cuando depure, haga las siguientes preguntas mentales, en este orden , cuando lea un mensaje de error:
nil
? ) En el seguimiento de la pila, preste especial atención a las líneas de código que provienen de su proyecto (por ejemplo, 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é es importante interpretar en este orden ...
Ejecutas código que en algún momento se ejecuta como tal:
@foo = Foo.new
...
@foo.bar
y obtienes un error que dice:
undefined method "bar" for Nil:nilClass
Los principiantes ven este error y piensan que el problema es que el método nobar
está definido . No es. En este error, la parte real que importa es:
for Nil:nilClass
for Nil:nilClass
significa que @foo
es nulo! @foo
no es una Foo
variable de instancia! Tienes un objeto que es Nil
. Cuando vea este error, es simplemente que 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 dejarse engañar para que piense que este error tiene que ver con bar
ser undefined
. Cuando no se lee con cuidado, este error hace que los principiantes vayan a cavar por error en los detalles del bar
método Foo
, omitiendo por completo la parte del error que sugiere que el objeto es de la clase incorrecta (en este caso: nulo). Es un error que se evita fácilmente al leer los mensajes de error en su totalidad.
Resumen:
Siempre lea cuidadosamente el mensaje de error completo antes de comenzar cualquier depuración. Eso significa: Siempre verifique primero el tipo de clase de un objeto en un mensaje de error , luego sus métodos , antes de comenzar a buscar en cualquier stacktrace o línea de código donde cree que puede estar ocurriendo el error. 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 o use un depurador irb en su lugar. Evite las madrigueras de conejo leyendo los errores cuidadosamente antes de depurar.
Imprima las variables siempre que sea posible. (Esto se denomina depuración de printf) Puede hacerlo ejecutando
STDERR.puts x.inspect
o
STDERR.puts "Variable x is #{x.inspect}"
Si desea que sea más fácil de escribir, puede utilizar la gema de ejemplo .
Encienda las advertencias. Si está ejecutando ruby
, ejecútelo con el -w
interruptor (por ejemplo ruby -w script.rb
). Si lo está ejecutando desde irb y está utilizando una versión de ruby anterior a 1.9.2, escriba $VERBOSE = true
al comienzo de su sesión. Si escribe mal una variable de instancia, una vez que las advertencias estén activadas, obtendrá
advertencia: variable de instancia
@valeus
no inicializada
Comprender 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 nuevamente y repita.
Si tiene é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 creas que volvería true
. En ese caso, es posible que desee ver la documentación. Los sitios web de documentación incluyen ruby-doc.org o APIdock . En el último caso, escribiría include?
junto a la lupa cerca de la esquina superior derecha, elegiría la include?
que tiene Array
debajo (si no sabe qué clase [1, 2, 3]
es, escriba [1, 2, 3].class
irb), y podrá incluir. (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 guión completo no está haciendo lo que debería.
borra todas las cosas
Bienvenido a 2017 ^ _ ^
De acuerdo, si no te opones a probar un nuevo IDE, puedes hacer lo siguiente de forma gratuita .
launch.json
uso "cwd"
y y "program"
campos utilizando la {workspaceRoot}
macro"showDebuggerOutput"
y configúrelo entrue
"debug.allowBreakpointsEverywhere": true
vscode
; Esto no es lo mismo que Visual Studio . Es gratis, liviano y generalmente considerado positivamente.View->Extensions
.vscode
y allí solo 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
}
]
}
File->Preferences->Settings
(o Ctrl,) y nos desplazaremos hasta llegar a la Debug
sección. Expanda y busque un campo llamado "debug.allowBreakpointsEverywhere"
: seleccione ese campo y haga clic en el pequeño icono con aspecto de lápiz y configúrelo 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: con todas las cosas divertidas como su pila de llamadas, visor variable, etc.
El mayor PITA es 1) instalar los requisitos previos y 2) Recordar configurar el .vscode\launch.json
archivo. Solo el n. ° 2 debería agregar equipaje a proyectos futuros, y puede copiar una configuración lo suficientemente genérica como la que se menciona arriba. Probablemente haya una ubicación de configuración más general, pero no lo sé.
Recomiendo este video para 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.
¡Esos son mis dos centavos!
Todas las demás respuestas ya dan casi todo ... Solo una pequeña adición.
Si desea más depurador tipo IDE (no CLI) y no tiene miedo de usar Vim como editor, le sugiero el complemento Vim Ruby Debugger para él.
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 una ventana ingeniosa en pausa, pasar / entrar, casi todas las características habituales del depurador.
Para mí fue bastante divertido usar este depurador vim para depurar una aplicación Rails, aunque las ricas capacidades de registro de Rails casi eliminan la necesidad de ello.
Acabo de descubrir esta gema (convierte a Pry en un depurador para MRI Ruby 2.0+)
https://github.com/deivid-rodriguez/pry-byebug
Instalar con:
gem install pry-byebug
luego use exactamente como pry
, marque la línea en la que desea romper:
require 'pry'; binding.pry
Sin embargo, a diferencia de Vanilla Pry, esta gema tiene algunos comandos clave de navegación tipo GDB como next
, step
y 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
bandera (advertencias)irb
es un excelente punto de partida. Intente usar irb con pequeños trozos cuestionables. Me encanta ruby-debug (ruby-debug19 para Ruby 1.9+) porque hace que sea más fácil detener el programa en ejecución, examinar variables, ingresar a irb y luego continuar ejecutándolo.
Para depurar fácilmente el script de shell Ruby, 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 (hasta la próxima Excepción, punto de interrupción o línea con:) debugger
,n
para la siguiente línea,w
/ where
Mostrar marco / pila de llamadas,l
para mostrar el código actual,cat
para mostrar puntos de captura.h
para más ayudaVer también: Depuración con ruby-debug , atajos de teclado para ruby-debug gem .
En caso de que el script simplemente se cuelgue y necesite una traza inversa, intente usar lldb
/ gdb
like:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
y luego verifique su proceso en primer plano.
Reemplazar lldb
con gdb
si funciona mejor. Prefijo con sudo
para depurar procesos no propios.
A partir de Ruby 2.4.0, es más fácil iniciar una sesión REPL de IRB en medio de cualquier programa de Ruby. Coloque estas líneas en el punto del programa que desea depurar:
require 'irb'
binding.irb
Puede ejecutar el código Ruby e imprimir variables locales. Escriba Ctrl + D o quit
para finalizar REPL y dejar que el programa Ruby siga ejecutándose.
También puede usar puts
e p
imprimir valores de su programa mientras se ejecuta.
Si está utilizando RubyMine , depurar scripts de ruby es simple y directo.
Supongamos que tiene un script Ruby hello_world.rb
Establezca un punto de interrupción en la línea 6 como se muestra a continuación.
Ahora puede iniciar el depurador para ejecutar el script:
Luego, cuando la ejecución llegue a un punto de interrupción, podrá inspeccionar variables, etc.
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 impresas, a otras les gusta profundizar con un depurador.
Te sugiero que pruebes ambos enfoques.
En realidad, uno de los viejos hombres de Unix dijo recientemente que la depuración de printf era una forma más rápida de conseguirlo en algunos puntos.
Pero si eres nuevo en algún trabajo y necesitas entender una gran cantidad de código, entonces es realmente útil dar un paso adelante, poner algunos puntos de interrupción aquí y allá, y seguir cómo funciona.
Debería darte una idea de cómo se teje el código.
Si usted es nuevo en el software de otras personas, podría ayudarlo a avanzar.
Descubrirá rápidamente si lo organizaron de una manera inteligente, o si eso es solo un montón de mierda.
Bueno, ruby lib estándar tiene un depurador de consola similar a gdb fácil de usar: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html No es necesario instalar gemas adicionales. Los scripts de Rails también se pueden depurar de esa manera.
p.ej
def say(word)
require 'debug'
puts word
end
La madre de todos los depuradores es la simple 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 así:
@result = fetch_result
p "--------------------------"
p @result
Esto imprimirá el contenido de @result a STDOUT con una línea en el frente para una fácil identificación.
Bonificación si usa un marco capaz de cargar / cargar automáticamente como Rails, ni siquiera necesitará reiniciar su aplicación. (A menos que el código que está depurando no se vuelva a cargar debido a la configuración específica del marco)
Creo que esto funciona para el 90% del caso de uso para mí. También puede usar ruby-debug, pero me parece excesivo la mayor parte del tiempo.
Hay muchos depuradores con diferentes características, en función de los cuales eliges. Mis prioridades estaban satisfechas con movimientos de palanca que eran: