如何为当前请求停止Rails调试器

Yuv*_*rmi 15 ruby debugging ruby-on-rails ruby-debug ruby-on-rails-3

假设我的代码中有一个循环调用rails调试器几次

def show
    animals = ['dog', 'cat', 'owl', 'tiger']
    for animal in animals
    debugger
    # do something else
end
Run Code Online (Sandbox Code Playgroud)

假设我使用该--debugger选项启动了我的服务器,当查看此页面时,调试器将在每次循环运行时停止.

我可以在cont每次停止时输入,因此请求仍在继续,但这很乏味,特别是如果我们不是在谈论它在这个示例中显示4次​​,而是400.有没有办法让调试器继续而不会暂停循环点?

我目前的解决方法是重新启动服务器,但这很耗时.

Mor*_*ori 16

只需在调试器语句上添加条件,使其仅在您需要时停止,例如:

debugger if animal == 'tiger'
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要仅在循环384上检查代码:

animals.each_with_index do |animal, i|
  debugger if i == 384
  # do something
end
Run Code Online (Sandbox Code Playgroud)

或者放入一个可以让你继续临时的变量:

continue_debugger = false
animals.each do |animal|
  debugger unless continue_debugger
  # in the debugger type `p continue_debugger = true` then `c` when done
end
Run Code Online (Sandbox Code Playgroud)


rub*_*olo 12

把你debugger的迭代之前声明的地方,然后设置一个断点迭代里面,你可以再清楚以后.

例:

def index

  debugger

  @things = Thing.all
  @things.each do |thing|
    # ... something you want to check out in the debugger
    thing.some_calculation
  end
end
Run Code Online (Sandbox Code Playgroud)

进入调试器时,在内部设置断点:

b app/controllers/things_controller.rb:42
Run Code Online (Sandbox Code Playgroud)

(其中42是你要打破的行号,thing.some_calculation如上所述.请注意,它必须是可执行的代码行 - 注释,空白行不起作用).调试器将显示断点编号和位置:

Breakpoint 1 at .../app/controllers/things_controller.rb:42
Run Code Online (Sandbox Code Playgroud)

现在,每次你继续,你都会在断点处停下来.当您完成并想要完成请求时,删除断点:

delete 1
Run Code Online (Sandbox Code Playgroud)

再次继续,您将完成请求!


Mat*_*att 5

看起来在ruby-debug的源代码中,调用debugger始终在命中时停止执行.因此,一个解决方案是按照Mori在他的'ad-hoc'解决方案中建议的那样做,以调用调试器的调用为条件,你可以在调试器会话本身内调整,这样你就可以避免调用debugger.这可能是最好的解决方案,除非你对所涉及的代码有一些强烈的唠叨纯度问题,否则我会做什么.

如果你真的只想在没有一些外部条件的情况下在调试器会话本身内执行此操作,那么它可能的.您需要做的是在代码本身中设置一个断点,然后您可以在调试器中触发它时删除该断点:

require 'rubygems'
require 'ruby-debug'

Debugger.start
Debugger.add_breakpoint(__FILE__, __LINE__ + 2)
while true do
  puts "Hi"
  puts "mom"
end
Debugger.stop
Run Code Online (Sandbox Code Playgroud)

这产生了这种互动:

Breakpoint 1 at debug_test.rb:10
debug_test.rb:10
puts "Hi"
(rdb:1) c
Hi
mom
Breakpoint 1 at debug_test.rb:10
debug_test.rb:10
puts "Hi"
(rdb:1) c
Hi
mom
Breakpoint 1 at debug_test.rb:10
debug_test.rb:10
puts "Hi"
(rdb:1) info b
Num Enb What
  1 y   at ./debug_test.rb:10
        breakpoint already hit 3 times
(rdb:1) del 1
(rdb:1) c
Hi
mom
Hi
mom
Hi
mom
Run Code Online (Sandbox Code Playgroud)

...等等.

这样,您将在代码中设置断点,然后在完成后将其删除.请注意,无论Debugger.add_breakpoint何时调用该行,它都将重新设置断点,这就是它在循环之外并指向2行的原因.这个技术很容易被提取到require一个脚本中,该脚本只在加载你的服务器时设置断点 - 哎呀,你可以根据需要编写一个完整的框架类来控制Debugger模块.当然,如果你走得这么远,我只会创建一个单例类来帮助你实现Mori的临时解决方案,并且不会或者不会调用调试器语句.