Como depuro os programas Ruby?
#insert code here
Mas não funciona!
Por favor, ajudem-me. O que posso fazer para depurar o programa sozinho?
17 answers
Utilizar ( GitHub ).
Instalar via:
$ gem install pry
$ pry
Depois adicionar:
require 'pry'
Para o seu programa.
-
Em Ruby:
ruby -rdebug myscript.rb
Então,
-
b <line>
colocar ponto de ruptura - e
n(ext)
ous(tep)
ec(ontinue)
-
p(uts)
para visualização
(como a depuração de perl)
-
-
Em Carris: lançar o servidor com
script/server --debugger
E adicionar
debugger
no código.
Como corrimão recomendado: utilizar pry! Só posso concordar com isso.
O Pry é muito melhor do que o irb.Tens de adicionar
require 'pry'
Para o seu ficheiro de origem e depois inserir um ponto de paragem no seu código-fonte, adicionando
binding.pry
No lugar onde você quer dar uma olhada nas coisas (isto é como activar um ponto de paragem num ambiente IDE clássico)
Assim que o teu programa atingir obinding.pry
Linha, vais ser atirado directamente para a pry repl, com todos o contexto do seu programa à mão, para que você possa simplesmente explorar tudo ao seu redor, investigar todos os objetos, muda de estado e até muda de código.
Acho que não pode alterar o código do método em que está actualmente., então você não pode, infelizmente, mudar a próxima linha a ser executada. Mas o bom código ruby tende a ser uma única linha de qualquer maneira; -)depuração aumentando as excepções is far easier than squinting through print
log statements, and for most bugs, its generally much faster than opening up an irb debugger like pry
or byebug
. Essas ferramentas não devem ser o seu primeiro passo.
A Depurar O Ruby / Rails Rapidamente.
1. Método rápido: obter um Exception
Depois e {[6] } o seu resultado
A forma mais rápida de depurar o código Ruby (especialmente os carris) é para raise
uma exceção ao longo do caminho de execução do seu código, enquanto chama .inspect
sobre o método ou objeto (e.g. foo
):
raise foo.inspect
No código acima, raise
dispara uma Exception
que interromperá a execução de seu código, e retorna uma mensagem de erro que convenientemente contém .inspect
informações sobre o objeto/método (por exemplo, foo
) na linha que você está tentando depurar.
Esta técnica é útil para rapidamente examinar um objecto ou método ([41]}por exemplo, é nil
?) e para confirmar imediatamente se uma linha de código está mesmo a ser executada num determinado contexto.
2. Recurso: usar um depurador de rubi como byebug
ou pry
Só depois de ter informações sobre o estado do seu fluxo de execução de códigos deve considerar mudar-se para um depurador de irb em ruby gem, como pry
ou byebug
, onde poderá aprofundar mais o estado dos objectos dentro da sua execução caminho.
Conselho De Principiante Geral Quando você está tentando depurar um problema, um bom conselho é sempre: lê o !@ # $ing mensagem de erro (RTFM)
Isso significa ler as mensagens de erro cuidadosamente e completamenteantes de agir para que você entenda o que está a tentar dizer-lhe. Quando depurar, faça as seguintes perguntas mentais, por esta ordem, ao ler um erro mensagem:
-
O que foi? classe o erro faz referência? (ou seja, tenho a classe de objeto correta ou o meu objeto
nil
?)
O que foi? método o erro faz referência? (i.e. é o seu tipo no método; posso chamar este método neste tipo/classe de objecto?)
Finalmente, usando o que posso inferir das minhas duas últimas perguntas, linhas de código devo investigar? (lembrar: a última linha de código na pilha de trace não é necessariamente onde o problema está.)
No traço da pilha, preste especial atenção às linhas de código que vêm do seu projecto (por exemplo, linhas que começam por app/...
se estiver a utilizar Carris). 99% das vezes o problema é com o seu próprio código.
Para ilustrar a importância da interpretação nesta ordem...
Por exemplo, uma mensagem de erro de Ruby que confunde muitos iniciantes:Você executa código que em algum momento executa como tal:
@foo = Foo.new
...
@foo.bar
E você tem um erro que diz:
undefined method "bar" for Nil:nilClass
Os principiantes vêem este erro e pensam que o problema é que o método bar
é indefinido. Não é. neste erro a parte real que importa é:
for Nil:nilClass
for Nil:nilClass
significa que @foo
é nula! @foo
não é uma variável de instância Foo
! Você tem um objeto que é Nil
. Quando você vê este erro, é simplesmente ruby tentando lhe dizer que o método bar
não existe para objetos da classe Nil
. (well duh! uma vez que estamos tentando usar um método para um objeto da classe Foo
Não Nil
).
undefined method "bar" for Nil:nilClass
é fácil ser enganado para pensar que este erro tem a ver com bar
ser undefined
. Quando não é lido com atenção, este erro faz com que os iniciantes, erroneamente, investiguem os detalhes do método bar
em Foo
, em falta a parte do erro que indica que o objeto é da classe errada (neste caso: zero). É um erro que é facilmente evitado lendo mensagens de erro na sua totalidade.
Resumo:
Sempre com cuidado leia a inteira mensagem de erro antes de iniciar qualquer depuração. Isso significa: classe tipo de objecto numa mensagem de erro primeiro, depois a sua métodos, antes de começar a procurar em qualquer stacktrace ou linha de código onde pensa que o erro possa estar a ocorrer. Esses 5 segundos podem poupar-lhe 5 horas de frustração.
TL; dr: Não fique parado nos registos de impressão: crie excepções em vez disso. Evite buracos de coelho lendo cuidadosamente erros antes de depuração.
-
Imprime as variáveis sempre que possível. (Isto é chamado de depuração printf) você pode fazer isso executando
STDERR.puts x.inspect
Ou
STDERR.puts "Variable x is #{x.inspect}"
Se quiser tornar isto mais fácil de digitar, então pode querer usar o exemplo gem.
-
Liga os avisos. Se você está executando
ruby
então execute-o com o botão-w
(egruby -w script.rb
). Se você está executando a partir de irb, e você está usando uma versão de ruby antes de 1,9.2, tipo$VERBOSE = true
no início do seu sessao. Se você escrever mal uma variável de instância, uma vez que os avisos estão ligados você vai terAtenção: instância variável
@valeus
não inicializada -
Compreender o conceito de um chop binário (a seguinte citação é de práticas de um desenvolvedor ágil)
Divide o espaço problema ao meio, e vê qual a metade que contém o problema. Então divide essa metade em metade outra vez, e repete.
-
Se tiveres sucesso com um chop binário, você pode descobrir que há uma única linha que não faz o que você espera que ele faça. Por exemplo
[1, 2, 3].include?([1,2])
Dá um valor de
false
, apesar de se pensar que voltariatrue
. Nesse caso, você pode querer olhar para a documentação. Os sítios web para documentação incluem ruby-doc.org , ou APIdock . Neste último caso, você digitainclude?
ao lado da lupa perto do canto superior direito, escolha oinclude?
que temArray
debaixo dela (se você não sabe qual é a classe[1, 2, 3]
, Tipo[1, 2, 3].class
no irb), e você consegue incluir ? (Array), que descreve o que faz.No Entanto, se a documentação não ajudar, você é mais provável para obter uma boa resposta, se você pode fazer uma pergunta sobre como uma determinada linha não está fazendo o que deveria, em vez de por um script inteiro não está fazendo o que deveria.
Se quiser mais depurador semelhante ao IDE (não-CLI) e não tiver medo de usar o Vim como editor, sugiro o 'plugin' do Ruby depurador para ele.
A sua documentação é bastante simples, por isso siga o link e veja. Em suma, permite-lhe definir o ponto de paragem na linha actual do editor, ver as variáveis locais na janela nifty em pausa, passar por cima/para dentro - quase todo o depurador habitual recurso. Para mim, foi muito agradável usar este depurador vim para depurar um aplicativo Rails, embora as habilidades de logger Rico de Rails quase eliminem a necessidade dele.- pode imprimir as suas variáveis pelo caminho
- Liga a bandeira {[[0]} (avisos)
- Utilize uma ferramenta como ruby-debug
Eu recomendo fortemente este vídeo, a fim de escolher a ferramenta adequada no momento para depurar o nosso código.
Https://www.youtube.com/watch?v=GwgF8GcynV0
Pessoalmente, destacaria dois grandes tópicos neste vídeo.- Pry é incrível para dados de depuração, "pry é um explorador de dados" (sic)
- depurador parece ser melhor depurar passo a passo.
Acabei de descobrir esta jóia (transforma o Pry num depurador para a RMN 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.
Para depurar facilmente o programa Ruby shell, basta mudar a sua primeira linha de:
#!/usr/bin/env ruby
To:
#!/usr/bin/env ruby -rdebug
Então, sempre que a consola do depurador for mostrada, você pode escolher:
-
c
para continuar (para a próxima excepção, ponto de paragem ou linha com:debugger
), -
n
para a próxima linha, -
w
/where
para mostrar a pilha de imagens / chamadas, -
l
para mostrar o código actual, - Para mostrar pontos de captura.
-
h
para mais Ajudar.
Ver também: depuração com depuração em ruby, atalhos de teclado para o gem de depuração em ruby.
No caso de o guião apenas estar pendurado e precisar de um backtrace, tente usar
lldb
/gdb
Tipo:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
E depois verificar o seu processo em primeiro plano.
Substituir lldb
por gdb
se funcionar melhor. Prefixo com sudo
para depurar o processo não detido.
apaga todas as coisas
Bem-vindo a 2017 Muito bem, se não te opuseres a experimentar um novo IDE, podes fazer o seguinte por " free ".Instruções Rápidas
- Instale o vscode
- Instale o Ruby Dev Kit se ainda não tiver
- instalar as extensões Ruby, ruby-linter e ruby-rubocop para VSCode
- instalar manualmente quaisquer pedras preciosas } rubiide/vscode-ruby especifica , se necessário
- Configure o seu
launch.json
para usar"cwd"
e e"program"
campos que usam a macro{workspaceRoot}
- adicione um campo chamado {[4] } e configure-o para
true
- activar os pontos de paragem em toda a parte nas suas preferências de depuração como
"debug.allowBreakpointsEverywhere": true
Instruções Detalhadas
- Download Visual Studio Code aka
vscode
; isto não é o mesmo que Visual Studio. É livre, leve e geralmente considerada positivamente. - Instale o Rubi Dev Kit; você deve seguir as instruções no seu repo aqui: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
- em seguida, você pode instalar extensões através de um navegador web, ou dentro do IDE; isto é para dentro do IDE. Se você escolher o outro, você pode ir aqui. Navegue para a parte de extensões do vscode; você pode fazer isso de algumas maneiras, mas o método mais à prova de futuro provavelmente será bater F1, e digitar para fora xT até uma opção chamada extensões: instalar extensões ficar disponível. As alternativas são CtrlShiftx e da barra de menu superior,
View->Extensions
A seguir vais querer as seguintes extensões, não são 100% necessárias, mas vou deixar-te decidir o que guardar depois de teres remendado algumas.:
- Ruby; autor da extensão Peng Lv
- ruby-rubocop; extension author misogi
- ruby-linter; autor de extensão Cody Hoover
-
launch.json
conteúdo
{
"version": "0.2.0",
"configurations":
[
{
"name": "Debug Local File",
"type":"Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "{workspaceRoot}/../script_name.rb",
"args": [],
"showDebuggerOutput": true
}
]
}
- siga as instruções dos autores da extensão para instalações manuais de gema. Está localizado aqui por agora.: https://github.com/rubyide/vscode-ruby#install-ruby-dependencies
- você provavelmente vai querer a capacidade de colocar pontos de paragem onde quiser; não ter esta opção activada pode causar confusão. Para isso, iremos à barra de menu superior e seleccionaremos
File->Preferences->Settings
(ou Ctrl, ) e rola até chegares à secçãoDebug
. Expande-o e procura um campo chamado"debug.allowBreakpointsEverywhere"
-- seleccione esse campo e carregue no pequeno ícone de aparência de lápis e configure-o paratrue
.
Depois de fazer todas as coisas divertidas, você deve ser capaz de definir pontos de interrupção e de depuração em um menu semelhante a esta para meados de 2017 e um tema mais escuro: com todas as coisas divertidas como a sua pilha de chamadas, visualização variável, etc.
O maior PITA é 1) Instalando os pré-reqs e 2) lembrando-se de configurar o arquivo .vscode\launch.json
. Apenas #2 deve adicionar qualquer bagagem para projetos futuros, e você pode apenas copiar uma configuração genérica o suficiente como a listada acima. Há deve ser uma localização mais geral, mas não sei de nada.
A partir de Ruby 2.4.0, é mais fácil iniciar uma sessão de REPL IRB no meio de qualquer programa de Ruby. Coloque estas linhas no ponto do programa que deseja depurar:
require 'irb'
binding.irb
Podes correr o código Ruby e imprimir as variáveis locais. Escreva Ctrl+D ou quit
para terminar a REPL e deixar o programa Ruby continuar em execução.
Você também pode usar puts
e p
para imprimir os valores do seu programa à medida que ele está em execução.
Depuração do Printf
Sempre houve uma Controvérsia em torno de técnicas de depuração., algumas pessoas gostam de depurar por declarações de impressão, alguns outros gostam de cavar fundo com um depurador. Sugiro que tentem ambas as abordagens. Na verdade, um dos antigos homens do Unix disse recentemente:, essa depuração printf foi uma maneira mais rápida de ir para ele em alguns pontos. Mas se você é novo em algum trabalho e precisa entender uma grande bolha de código, então é realmente útil para passo por ali, colocar alguns pontos de paragem aqui e ali, a seguir como funciona. Deve dar-te alguma compreensão de como o código é tecido.Se você é novo em algum software de outras pessoas, Pode ajudar-te a passar por lá.
Vais descobrir rapidamente se eles o arranjaram de uma forma inteligente., ou se for só um monte de merda.A mãe de todo o depurador é um ecrã de impressão simples e antigo. Na maioria das vezes, você provavelmente só quer inspecionar alguns objetos simples, uma maneira rápida e fácil é assim:
@result = fetch_result
p "--------------------------"
p @result
Isto irá imprimir o conteúdo do @result para o STDOUT com uma linha na frente para fácil identificação.
Bónus se usar uma estrutura capaz de carregar / carregar automaticamente como os carris, nem sequer terá de reiniciar a aplicação. (A menos que o código que você está debugging não seja recarregado devido a configurações específicas do framework)
Acho que isto funciona para 90% do caso de uso para mim. Você também pode usar ruby-debug, mas eu acho que ele exagera na maioria das vezes.Bem, o ruby standard lib tem um depurador de consola fácil de usar semelhante ao gdb: http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html Não há necessidade de instalar qualquer jóia extra. Os scripts do Rails também podem ser depurados dessa forma.
Por exemplo
def say(word)
require 'debug'
puts word
end
Se estiver a utilizar RubyMine , a depuração dos programas de ruby é simples e simples.
Suponha que você tem um roteiro em Ruby hello_world.rb1. Definir os pontos de paragem
Define um ponto de paragem na linha 6 como em baixo.
2. Iniciar a depuração
Agora pode iniciar o depurador para executar o programa:
3. Inspeccionar variáveis, etc.
Então, quando a execução chegar um ponto de paragem, você será capaz de inspecionar variáveis, etc.Mais informações para a sua referência
- Se quiser usar Rubimina para fazer depuração remota , pode fazê-lo.
- Se quiser usar a Rubimina para depurar os carris remotos dentro de um acoplador, também é simples.
Há muitos depuradores com características diferentes, com base nas quais você faz a escolha. As minhas prioridades estavam satisfeitas com os movimentos indiscretos que eram:
- informação rapidamente compreensível sobre como utilizar Passos intuitivos (como entrar facilmente em blocos)
- " passo para trás "(mover-se parcialmente satisfaz a necessidade)