【问题标题】:How to debug ruby code?如何调试 ruby​​ 代码?
【发布时间】:2011-05-06 15:51:08
【问题描述】:

我运行的是 Ubuntu 10.10。我只想调试一个简单的脚本。在花了半天时间试图弄清楚如何做到这一点后,我放弃了。我该怎么办?

我从 Ubuntu 存储库安装了 ruby-dev
我跑了sudo gem install ruby-debugsudo gem install ruby-debug-ide

我尝试了几种不同的方法来完成这项工作。我尝试了require 'ruby-debug',然后在代码中的某处设置了debugger。但是 Ruby 找不到 ruby-debug
我尝试设置vim-ruby-debugger,这将花费ages 来执行:Rdebugger myScript.rb 并允许我设置断点,但似乎没有办法使用该调试器执行我的代码。
我尝试使用 NetBeans,每次设置项目并单击任何内容时都会崩溃。

所以,亲爱的社区:必须有调试 Ruby 的方法。不是导轨。没有什么花哨。只是一些 CLI 脚本。请帮助我,否则我会失去理智。

编辑: gem exec 目录不在我的路径中。所以,至少 rdebug 现在似乎可以工作了。

【问题讨论】:

标签: ruby debugging


【解决方案1】:

要调试 Ruby 代码,您需要两个 gem:prypry-byebug

这是一个简单的 Ruby 脚本,它将两个数字相加并打印它们的总和。注意底部的binding.pry 语句。该语句添加了一个断点并告诉 Ruby 在该点停止执行。此时,我们可以检查当前状态,步入和退出方法,退出或继续执行。

require "pry"
require "pry-byebug"

class Sandbox
  def add(a, b)
    sum = a + b
    sum
  end
end

puts "Welcome to the Sandbox"

binding.pry

box = Sandbox.new
sum = box.add(3, 4)

puts "Sum = #{sum}"

如果您要在终端中运行此代码,您会看到以下代码。 Pry 暂停程序,终端正在等待您的输入。请注意行号旁边的箭头,它告诉您控件的确切位置。

➜  sandbox (main) ✗ ruby lib/sandbox.rb
Welcome to the Sandbox

From: /../sandbox/lib/sandbox.rb:15 :

    10:
    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
 => 15: box = Sandbox.new
    16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

[1] pry(main)>

在终端上输入next 转到下一行。

[1] pry(main)> next

From: /../sandbox/lib/sandbox.rb:16 :

    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
    15: box = Sandbox.new
 => 16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

[1] pry(main)>

在终端中输入 step 以进入 add 方法。 Pry 将带您进入 add 方法。

[1] pry(main)> step

From: /../sandbox/lib/sandbox.rb:6 Sandbox#add:

    5: def add(a, b)
 => 6:   sum = a + b
    7:   sum
    8: end

在调试期间,您可以通过在终端中输入 ls 或简单地输入变量名来检查局部变量。例如,输入a 会显示a 变量的值。

[1] pry(#<Sandbox>)> a
=> 3

键入up 退出此方法,这会使您在堆栈中上一层。我经常这样做,尤其是当我在调试时发现自己处于框架代码中时。

[2] pry(#<Sandbox>)> up

From: /Users/akshayk/Dev/ruby/sandbox/lib/sandbox.rb:16 :

    11: puts "Welcome to the Sandbox"
    12:
    13: binding.pry
    14:
    15: box = Sandbox.new
 => 16: sum = box.add(3, 4)
    17:
    18: puts "Sum = #{sum}"

要继续执行直到控件到达下一个断点,请键入continue。输入exit 退出调试。

如果您想在任何时间点查看自己的位置,请输入 @whereami,pry 会显示当前断点。当您阅读帮助时(通过在调试时在终端中输入帮助)或已清除终端并想查看执行时的位置,您可能会发现这很有帮助。

这就是调试 Ruby 代码的方式。希望对您有所帮助。

来源:How to Debug Ruby Code

【讨论】:

    【解决方案2】:

    有很多基于控制台的 ruby​​ 调试器具有不同的功能,您可以根据这些调试器做出选择。

    如果您有重要的需求 - 是直观的导航(例如,下一步逐行移动、进入块)和快速可理解的文档 - 这对我来说是最好的:

    https://github.com/garmoshka-mo/pry-moves


    我需要的其他很酷的功能是从调试器内部进行调试。就像我在控制器的动作中停下来一样:

    def index
        list = Orders.for_user(current_user) 
    =>  binding.pry
    end
    

    现在我想了解为什么list 是空的? - 我可以运行debug Orders.for_user(current_user) 看看那里发生了什么

    【讨论】:

      【解决方案3】:

      Ruby 调试有一段艰难的历史,到处都是仅支持特定次要版本的 MRI 的工具。值得庆幸的是,对于 2.0 及更高版本,您可以使用 byebug

      命令行使用很简单:运行byebug &lt;your script&gt;。您还可以编辑文件并将 byebug 函数调用放在要启动调试的任何位置。

      【讨论】:

        【解决方案4】:

        Ruby-debug 适用于 1.8+,而 ruby​​-debug19 适用于 1.9+。

        ruby-debug 易于学习且非常有用。您可以告诉应用程序运行直到某个条件存在,然后让它中断,以便轻松定位 nil 值或其他偶尔发生的条件。

        在命令行中使用rdebug appname,您将在调试器提示符下结束。如果要运行到第 100 行并停止,可以输入c 100,调试器将设置一个临时断点,如果程序在执行路径中,程序将运行然后停在那里。一旦停止,临时断点将被清除。如果您总是想在第 100 行停止,您可以执行 b 100 然后 c 并且调试器将设置一个永久断点,继续,然后在到达断点时停止。您可以清除断点,设置在某些条件适用时发生的条件断点等。您可以键入n 跳到下一条指令跳过子例程调用,或输入s 单步执行。有以各种方式显示变量内容的命令,因此请阅读文档。

        从 rdebug 内部,您可以放入已经填充变量的 IRB shell,这样您就可以查看发生了什么。您可以从内部检查或设置值,帮助进行假设调整。如果您在 rdebug 中执行此操作,您可以使用更改后的值继续程序并查看其行为方式。

        IRB 有它的位置,它非常适合尝试,但它不能替代调试器,就像调试器可以做一些 IRB-ish 的事情,但不会替代它。这两种工具是一个很好的组合,并且可以避免依赖打印语句或转储到日志文件。


        Pry 已成为 IRB 和 debugger 的完美组合,非常值得研究。

        【讨论】:

        • 习惯于使用图形调试器,ruby-debug 起初使用起来有点尴尬,但最终证明它非常实用,并且肯定发现了我的错误。感谢您的提示!
        • 图形调试器很漂亮,但它们提供的功能必须存在于较低级别,在图形之下,否则它们将没有任何东西可呈现。我在命令行上花费了太多时间,以至于忘记了 IDE 中漂亮的布局。尽管如此,我还是依靠命令行调试器向我展示了变量中真正隐藏的内容。我对它应该是什么有自己的看法,但有时口译员不同意我的看法——而且它总是赢,直到我告诉它不同。 :-)
        • 请结帐pry-byebug,现在似乎是常态。
        • 我将链接更改为 pry-byebug。谢谢。
        【解决方案5】:

        通过以下方式尝试默认的 Ruby 调试器:

        ruby -r debug filename[, ...] 
        

        或者如果是 CLI 脚本,只需将其第一行更改为:

        #!/usr/bin/env ruby
        

        到:

        #!/usr/bin/env ruby -rdebug
        

        并且脚本将在每个异常处停止。

        或查看以下脚本示例:

        #!/usr/bin/env ruby
        class Hello
           def initialize( hello )
              @hello = hello
           end
           def hello
              @hello
           end
        end
        
        salute = Hello.new( "Hello, Mac!" )
        puts salute.hello
        

        可以如下图调试:

        # ruby -r debug hello.rb
        Debug.rb
        Emacs support available.
        
        hello.rb:3:class Hello
        (rdb:1) v l
          salute => nil
        (rdb:1) b 10
        Set breakpoint 1 at hello.rb:10
        (rdb:1) c
        Hello, Mac!
        

        来源:Ruby Debugger


        或者使用lldb/gdb。请参阅下面将脚本回溯打印到前台的简单示例:

        echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
        

        如果效果更好,请将lldb 替换为gdb。前缀sudo 调试非拥有进程。

        【讨论】:

        • 什么概念。使用内置调试器。谁曾想到。无论如何,它对我有用。 ruby-debug 是作为默认调试器加入到 ruby​​ 命令中的,还是与众不同的?
        • 不知道,我什至不是 Ruby 开发人员,但我不得不在某个我不知道的地方调试一些代码。
        【解决方案6】:

        您可以看到备忘单正在运行

          gem install cheat
          cheat rdebug
        

        这将显示使用 rdebug 的有用命令。

        【讨论】:

          【解决方案7】:

          pry 比 IRB 更好。以下内容来自其README

          Pry 是 Ruby 标准 IRB shell 的强大替代品。它是从头开始编写的,提供了许多高级功能,包括:

          • 源代码浏览(包括带有 pry-doc gem 的核心 C 源代码)
          • 文档浏览
          • 实时帮助系​​统
          • 在编辑器中打开方法(edit-method Class#method)
          • 语法高亮
          • 命令 shell 集成(在 Pry 中启动编辑器、运行 git 和 rake)
          • Gist 集成
          • 状态导航(cd、ls 和好友)
          • 运行时调用(使用 Pry 作为开发者控制台或调试器)
          • 外来对象支持(BasicObject 实例、IClasses、...)
          • 强大而灵活的指挥系统
          • 能够查看和回放历史记录

          • 受 IPython、Smalltalk 和其他高级 REPL 启发的许多便捷命令

          • 提供远程会话、完整调试功能等的大量插件。

          Pry 的目标不仅仅是替代 IRB;它试图将 REPL 驱动的编程引入 Ruby 语言。它目前不如用于 lisp 的 SLIME 等工具强大,但这是 Pry 的大体方向。

          Pry 也相当灵活,允许重要的用户自定义设置它以读取具有 readline 方法的任何对象并写入具有 puts 方法的任何对象 - Pry 的许多其他方面也是可配置的,使其成为实现自定义 shell 的不错选择。

          【讨论】:

          • 我同意,我在为 ruby​​ 1.9.3 安装 ruby​​-debug 时并不开心。 Pry 开箱即用,非常易于使用。
          • 在这里投票。非常类似于 python 的 pdb.set_trace() - 我正在寻找类似的东西。如 Nosh 所述,在 1.9.3 中开箱即用。
          • “pry 比 IRB 更好”:直到 Pry.debugger 出现在 2012 年年中之前都是如此。
          • 不知道为什么人们坚持称pry为“调试器”——它没有对步进、继续等的开箱即用支持。
          【解决方案8】:
          1. 在 Ruby 中:

            ruby -rdebug myscript.rb 那么,

            • b : 放置断点
            • and n(ext) or s(tep) and c(ontinue)
            • p(uts) 用于显示
          2. 在 Rails 中:使用

            启动服务器
            • 脚本/服务器 --debugger

              并在代码中添加调试器。

          【讨论】:

            【解决方案9】:

            使用 IRB。它是一个交互式 Ruby shell。当发生错误时,它会提供带有行号的跟踪,以便您可以判断代码的哪一部分出错了。您可以load您的源文件并运行各个方法以查看它们是否正常工作。 IRB 提供有用的输出 - 当您输入一些代码时,它会计算表达式,然后使用 .inspect 打印返回值。

            【讨论】:

            • Pry 比 IRB 更有效。它提供了更多的灵活性,并且它的社区也在不断发展(并与 IRB 的社区互操作)。
            【解决方案10】:

            我用过的最好的 Ruby 调试器是 Netbeans 内置的调试器。您必须从 Netbeans 安装快速 ruby​​ 调试器 gem(我不确定它实际上是哪个 gem,但 Netbeans 会提示您这样做)。我发现如果将 Netbeans 从内置的 JRuby 1.4 切换到系统的默认 Ruby 安装,效果会更好。还有值得一看的breakpoint gem,从开发开始就使用Ruby 内置库logger 也很有帮助。祝你好运!

            【讨论】:

            • Netbeans 每次我想运行它时都会崩溃。不过,如果我的调试需求超出了 ruby​​-debug 所能提供的,我肯定会检查一下。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多