我的 2025 年 Ruby 调试技巧

这是一份关于 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 LSPCode 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_ENABLE0,如在 CI 上设置会使debuggerbinding.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.gemIRB的集成以获得更好调试体验,可通过设置RUBY_DEBUG_IRB_CONSOLE1DEBUGGER__::CONFIG[:irb_console]true
  • debug.gemsteps)、nextn)、continuec)、finishfin)、untilu)、updown等命令在按下enter时会重复。
  • 可使用debugger(do: "...")debugger(pre: "...")在断点命中后自动执行命令,如debugger(pre: "info locals")打印本地变量并打开控制台,debugger(do: "info locals")打印本地变量并继续程序。
  • trace exceptioncatch [exception]命令组合可使调试控制流相关错误更易,trace exception在异常抛出时打印跟踪,catch [exception]在异常抛出时中断。
  • bt [n]up/down命令组合比在同一代码路径设置多个断点更有效。
  • 若要更精细跟踪,可使用tracer gem
  • debug.gem进入断点时会冻结所有运行线程,若有问题可使用binding.irb替代。
  • 可使用binding.irb进行轻量级调试打开 REPL,然后用debug命令激活debug.gem
  • 若想学习更多基本调试概念,2022 年 RubyKaigi 的演讲仍有帮助。
    希望这些技巧有用,祝调试愉快!
阅读 9
0 条评论