我如何调试Ruby脚本?

时间:2010-10-17 23:01:55

标签: ruby debugging

我从互联网上复制了以下Ruby代码并进行了一些更改。

但它不起作用!

请帮忙。我可以做些什么来自己调试程序?

17 个答案:

答案 0 :(得分:132)

使用PryGitHub)。

通过以下方式安装:

$ gem install pry
$ pry

然后添加:

require 'pry'

进入你的程序。

答案 1 :(得分:110)

  1. 在Ruby中:

    ruby -rdebug myscript.rb 
    

    然后,

    • b <line>:put break-point
    • n(ext)s(tep)c(ontinue)
    • p(uts)用于显示

    (如perl调试)

  2. 在Rails中:使用

    启动服务器
    script/server --debugger
    

    并在代码中添加debugger

答案 2 :(得分:54)

栏杆推荐:使用撬! 我只能同意这一点。

pry是一个比irb更好的代表。

您需要添加

require 'pry'

到你的源文件 然后通过添加

在源代码中插入断点
binding.pry

在你要看的东西的地方 (这就像在经典IDE环境中触发断点一样)

一旦你的节目点击了

binding.pry

一行,你会被扔进撬副本, 随着你的程序的所有上下文, 这样你就可以简单地探索周围的一切,调查所有物体, 改变状态,甚至动态改变代码。

我相信你无法改变你当前所处方法的代码, 所以你可以遗憾地不改变下一行要执行。 但无论如何,好的红宝石代码往往是单行; - )

答案 3 :(得分:28)

通过引发异常进行调试 比忽略print日志语句更容易,对于大多数错误,它通常< em>快得多比打开像prybyebug这样的irb调试器。这些工具不应该是你的第一步。

快速调试Ruby / Rails:

1。快速方法:提高Exception然后.inspect结果

调试Ruby(尤其是Rails)代码的最快方式是在代码的执行路径上raise异常,同时在方法或对象上调用.inspect(例如foo):

raise foo.inspect

在上面的代码中, raise 会触发 Exception 停止执行代码,并返回在您尝试调试的行上方便地包含有关对象/方法(即.inspect)的foo信息的错误消息。

此技术对于快速检查对象或方法(例如是nil)以及立即确认代码行是否均匀非常有用在给定的上下文中完全执行。

2。后备:使用ruby IRB 调试器,如byebugpry

只有在您获得有关代码执行流程状态的信息后,才应考虑转移到像prybyebug这样的ruby gem irb调试器,您可以在其中深入研究对象的状态你的执行路径。

一般初学者建议

当您尝试调试问题时,建议总是: 阅读!@#$ ing错误消息(RTFM)

这意味着在执行操作之前,请仔细阅读 阅读错误信息时,以下心理问题按此顺序

  1. 错误引用 是什么意思? (即我是否拥有正确的对象类或是我的对象nil
  2. 方法 是什么错误参考? (即是他们在方法中的类型;我可以在这个类型/对象类上调用此方法吗?
  3. 最后,使用我在上两个问题中可以推断的内容,我应该调查哪些 代码行 ? (记住:堆栈跟踪中的最后一行代码不一定是问题所在。)
  4. 在堆栈跟踪中,要特别注意来自项目的代码行(例如,如果使用Rails,则以app/...开头的行)。 99%的时间问题出在你自己的代码上。

    说明为什么按此顺序解释 很重要......

    E.g。一条令许多初学者感到困惑的Ruby错误消息:

    执行在某些时候执行的代码:

    @foo = Foo.new
    
    ...
    
    @foo.bar
    

    并且您收到错误消息:

    <强> undefined method "bar" for Nil:nilClass

    初学者会看到此错误,并认为问题是方法bar 未定义不是。在这个错误中,真正重要的部分是:

    for Nil:nilClass

    for Nil:nilClass表示@foo为Nil! @foo不是Foo实例变量!您有一个Nil的对象。当您看到此错误时,只是ruby试图告诉您类bar的对象不存在方法Nil。 (好吧!因为我们正在尝试为类Foo的对象使用方法而不是Nil)。

    不幸的是,由于编写此错误的方式(undefined method "bar" for Nil:nilClass),很容易让人误以为这个错误与bar undefined有关。如果没有仔细阅读,这个错误会导致初学者错误地深入研究barFoo方法的详细信息,完全忽略了提示该对象属于错误类的错误部分(在此案例:无)。通过完整阅读错误消息可以轻松避免这种错误。

    摘要:

    在开始任何调试之前,请务必小心阅读整个错误消息。这意味着:请务必先在首先错误消息中检查对象的 类型,然后检查 方法 之前您开始调查任何您认为可能发生错误的堆栈跟踪或代码行。这5秒钟可以为你节省5个小时的挫折感。

    tl; dr:不要斜视打印日志:改为引发异常。通过在调试之前仔细阅读错误来避免兔子洞。

答案 4 :(得分:19)

  1. 尽可能打印出变量。 (这称为printf调试)您可以通过运行

    来完成此操作
    STDERR.puts x.inspect
    

    STDERR.puts "Variable x is #{x.inspect}"
    

    如果您想让这更容易打字,那么您可能想要使用exemplor gem。

  2. 打开警告。如果您正在运行ruby,请使用-w开关(例如ruby -w script.rb)运行它。如果您是从irb运行它,并且在1.9.2之前使用的是ruby版本,请在会话开始时键入$VERBOSE = true。如果拼错了一个实例变量,一旦出现警告,你就会得到

      

    警告:实例变量@valeus未初始化

  3. 理解二元斩的概念(以下引用来自Practices of an Agile Developer

      

    将问题空间分成两半,看看哪一半包含问题。然后再将这一半分成两半,然后重复。

  4. 如果您使用二进制印章成功,您可能会发现有一行不符合您的预期。例如

    [1, 2, 3].include?([1,2])
    

    的值为false,即使您认为它会返回true。在这种情况下,您可能需要查看文档。文档的网站包括ruby-doc.orgAPIdock。在后一种情况下,您在右上角附近的放大镜旁边键入include?,选择其下方有include?的{​​{1}}(如果您不知道哪个类Array是,在irb中输入[1, 2, 3],然后转到include? (Array),其中描述了它的作用。

    但是,如果文档没有帮助,如果您可以询问特定行如何不应该执行的操作,那么您更有可能得到一个好答案,而不是为什么整个脚本不是'做他们应该做的事。

答案 5 :(得分:7)

删除所有内容

欢迎来到2017 ^ _ ^

好的,如果您不反对尝试使用新的IDE,可以执行以下操作 free

快速说明

  1. 安装vscode
  2. 安装Ruby Dev Kit(如果您还没有
  3. 为vscode安装Ruby,ruby-linter和ruby-rubocop扩展
  4. 如果需要,手动安装任何宝石rubyide/vscode-ruby specifies
  5. 使用launch.json
  6. "cwd"配置为使用"program"以及 {workspaceRoot}字段
  7. 添加名为"showDebuggerOutput"的字段并将其设置为true
  8. 在“调试”首选项中的所有位置启用断点"debug.allowBreakpointsEverywhere": true
  9. 详细说明

    1. 下载Visual Studio Code又名vscode;这与Visual Studio不同。它是免费的,重量轻的,并且通常都是积极的。
    2. 安装Ruby Dev Kit;你应该按照他们在这里的回购说明进行操作:https://github.com/oneclick/rubyinstaller/wiki/Development-Kit
    3. 接下来,您可以通过Web浏览器或IDE内部安装扩展程序;这是在IDE内部。如果你选择另一个,你可以去here。导航到vscode的Extensions部分;您可以通过几种方式实现这一目标,但最具前瞻性的方法可能是点击 F1 ,输入 e x t ,直到名为 Extensions:Install Extensions 的选项变为可用。替代方案是 Ctrl Shift x ,并从顶部菜单栏View->Extensions
    4. 接下来,您将需要以下扩展程序;这些都不是100%必要的,但我会让你决定在你修改一些之后要保留什么:
      • 红宝石;扩展作者彭吕
      • 红宝石rubocop;扩展作者misogi
      • 红宝石棉短绒;扩展作者Cody Hoover
    5. 在ruby脚本的目录中,我们将通过名为.vscode的命令行创建一个目录,在那里我们只有一个名为launch.json的文件,我们将在那里存储一些配置选项。
      • launch.json内容
    6. { "version": "0.2.0", "configurations": [ { "name": "Debug Local File", "type":"Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "{workspaceRoot}/../script_name.rb", "args": [], "showDebuggerOutput": true } ] }

      1. 按照扩展作者的说明进行手动gem安装。它暂时位于此处:https://github.com/rubyide/vscode-ruby#install-ruby-dependencies
      2. 您可能希望能够在任何地方放置断点;没有启用此选项会导致混淆。为此,我们将转到顶部菜单栏并选择File->Preferences->Settings(或 Ctrl )并滚动,直至到达Debug部分。展开它并查找名为"debug.allowBreakpointsEverywhere"的字段 - 选择该字段并单击小铅笔图标并将其设置为true
      3. 在完成所有有趣的事情之后,您应该能够在2017年中期的类似菜单中设置断点和调试以及更暗的主题:enter image description here以及所有有趣的内容,例如调用堆栈,变量观众等。

        最大的PITA是1)安装pre-reqs和2)记住配置.vscode\launch.json文件。只有#2应该将任何行李添加到未来的项目中,您只需复制一个通用的配置,就像上面列出的那样。可能有更一般的配置位置,但我不知道我的头脑。

答案 6 :(得分:6)

所有其他答案已经提供了几乎所有内容......只是一点点补充。

如果你想要一些类似IDE的调试器(非CLI)并且不怕使用Vim作为编辑器,我建议使用Vim Ruby Debugger插件。

它的文档非常简单,请点击链接查看。简而言之,它允许您在编辑器中设置当前行的断点,在暂停时在漂亮的窗口中查看局部变量,逐步调整/进入 - 几乎所有常用的调试器功能。

对我来说,使用这个vim调试器调试Rails应用程序非常有趣,尽管rich logger abilities的Rails几乎不需要它。

答案 7 :(得分:5)

  1. 您可以在途中打印变量
  2. 启用-w(警告)标记
  3. 使用ruby-debug
  4. 等工具

答案 8 :(得分:5)

从Ruby 2.4.0开始,在任何Ruby程序中都可以更轻松地启动IRB REPL会话。将这些行放在要调试的程序中的位置:

quit

您可以运行Ruby代码并打印出局部变量。键入Ctrl + D或puts以结束REPL并让Ruby程序继续运行。

您还可以使用p"@@session"在程序运行时打印出程序中的值。

答案 9 :(得分:5)

要轻松调试Ruby shell脚本,只需更改其第一行:

#!/usr/bin/env ruby

为:

#!/usr/bin/env ruby -rdebug

然后每次显示调试器控制台时,您都可以选择:

  • c表示继续(到下一个例外,断点或行:debugger),
  • n代表下一行,
  • w / where显示框架/调用堆栈,
  • l显示当前代码,
  • cat显示抓点。
  • h获取更多帮助。

另请参阅:Debugging with ruby-debugKey shortcuts for ruby-debug gem

如果脚本只是hangs并且您需要回溯,请尝试使用lldb / gdb,如:

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

然后检查您的流程前景。

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

答案 10 :(得分:5)

我刚发现这个gem(将Pry变成MRI Ruby 2.0+的调试器)

.net fiddle

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.

答案 11 :(得分:5)

我强烈推荐这个视频,以便选择适当的工具来调试我们的代码。

https://www.youtube.com/watch?v=GwgF8GcynV0

就个人而言,我将在本视频中重点介绍两个重要主题。

  • Pry对于调试数据非常棒,“pry是一个数据浏览器”(原文如此)
  • 调试器似乎更好地逐步调试。

那是我的两分钱!

答案 12 :(得分:3)

如果您使用的是RubyMine,则调试ruby脚本非常简单明了。

假设您有一个Ruby脚本hello_world.rb

1。设置断点

在第6行设置断点,如下所示。

enter image description here

2。开始调试

现在您可以启动调试器来运行脚本:

enter image description here

enter image description here

3。检查变量等

然后当执行到达断点时,您将能够检查变量等。

enter image description here

供参考的更多信息

  1. 如果您想use RubyMine to do remote debugging,可以这样做。
  2. 如果您想use RubyMine to remote debug rails running inside a docker,也很简单。

答案 13 :(得分:2)

好吧,ruby标准lib有一个易于使用的类似gdb的控制台调试器: https://developers.google.com/android/reference/com/google/android/gms/maps/model/TileProvider 无需安装任何额外的宝石。 Rails脚本也可以这样调试。

e.g。

def say(word)
  require 'debug'
  puts word
end

答案 14 :(得分:2)

printf debugging

关于调试技术一直存在争议, 有些人喜欢用print语句调试, 其他一些人喜欢用调试器深入挖掘。

我建议您尝试这两种方法。

其实有一位老Unix男人最近说过, 在某些方面,printf调试是一种更快捷的方式。

但是,如果你是一个新工作,需要了解一大堆代码, 然后步入那里真的很有用, 在这里和那里放一些断点, 与它一起工作的方式。

它应该让您了解代码是如何编织的。

如果您是其他人的软件新手, 它可能会帮助您逐步完成。

你会很快发现他们是否以巧妙的方式安排了它, 或者如果那只是一堆狗屎。

答案 15 :(得分:1)

所有调试器的母亲都是普通的旧打印屏幕。大多数情况下,您可能只想检查一些简单的对象,快速简便的方法是这样的:

@result = fetch_result

p "--------------------------"
p @result

这将打印出@result到STDOUT的内容,前面有一行,便于识别。

如果您使用像Rails这样的自动加载/重新加载功能的框架,您甚至不需要重新启动应用程序。 (除非由于框架特定设置而未重新加载您正在调试的代码)

我觉得这适用于90%的用例。你也可以使用ruby-debug,但我发现它在大多数情况下都是过度的。

答案 16 :(得分:1)

有许多调试器具有不同的功能,您可以根据这些功能进行选择。我的优先事项满足pry-moves,即:

  • 快速了解如何使用
  • 的信息
  • 直观的步骤(比如轻松踩到街区)
  • “退后”(撬动部分满足需要)