这是一份关于 Ruby 调试技巧和建议的快速且未经打磨的集合:
- 可使用Ruby LSP 扩展连接到debug.gem,需不同的
launch.json配置,能更好处理连接问题,示例为https://github.com/Shopify/ruby-lsp/blob/main/.vscode/launch.json。 尝试在
launch.json中使用launch请求而非attach,可简化调试过程,如在大多数 Rails 项目中可这样配置:{ "version": "0.2.0", "configurations": [ { "type": "ruby_lsp", "name": "Launch Server", "request": "launch", "program": "bin/rails s", }, ] }- 调试会话效果依赖在方法、类和文件间的导航能力,要有好的编辑器设置,如Ruby LSP,且不只适用于 VS Code,许多其他编辑器也可用。
- 使用Ruby LSP的Code Lens功能在终端和 VS Code 中轻松调试测试,还制作了ruby-lsp-rspec提供 RSpec 测试的代码透镜。
- 在
Gemfile中使用gem "debug", require: "debug/prelude",debug.gem在需要时激活,通过require "debug/prelude"定义断点方法但不会立即激活 gem,Rails 7.2 起为新生成项目默认。 - 若想在某些环境中阻止debug.gem使用,可设置
RUBY_DEBUG_ENABLE为0,如在 CI 上设置会使debugger或binding.break报错而不是无限挂起。 可配置debug.gem在调试时忽略某些 gem,如:
begin # 尝试加载 debug 但只加载配置组件以防意外激活 require "debug/config" zeitwerk_paths = Gem.loaded_specs["zeitwerk"].full_require_paths.freeze bootsnap_paths = Gem.loaded_specs["bootsnap"].full_require_paths.freeze DEBUGGER__::CONFIG[:skip_path] = Array(DEBUGGER__::CONFIG[:skip_path]) + zeitwerk_paths + bootsnap_paths rescue LoadError # 以防因任何原因未安装 debug.gem,如在生产环境加载此文件时通常未安装 end若使用
Sorbet,可将sorbet-runtime添加到忽略列表:sorbet_paths = Gem.loaded_specs["sorbet-runtime"].full_require_paths.freeze DEBUGGER__::CONFIG[:skip_path] = Array(DEBUGGER__::CONFIG[:skip_path]) + sorbet_paths- 对于大多数用户,推荐激活debug.gem与IRB的集成以获得更好调试体验,可通过设置
RUBY_DEBUG_IRB_CONSOLE为1或DEBUGGER__::CONFIG[:irb_console]为true。 - debug.gem的
step(s)、next(n)、continue(c)、finish(fin)、until(u)、up、down等命令在按下enter时会重复。 - 可使用
debugger(do: "...")或debugger(pre: "...")在断点命中后自动执行命令,如debugger(pre: "info locals")打印本地变量并打开控制台,debugger(do: "info locals")打印本地变量并继续程序。 trace exception和catch [exception]命令组合可使调试控制流相关错误更易,trace exception在异常抛出时打印跟踪,catch [exception]在异常抛出时中断。bt [n]与up/down命令组合比在同一代码路径设置多个断点更有效。- 若要更精细跟踪,可使用tracer gem。
- debug.gem进入断点时会冻结所有运行线程,若有问题可使用
binding.irb替代。 - 可使用
binding.irb进行轻量级调试打开 REPL,然后用debug命令激活debug.gem。 - 若想学习更多基本调试概念,2022 年 RubyKaigi 的演讲仍有帮助。
希望这些技巧有用,祝调试愉快!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。