我如何debuggingRuby脚本?

我从互联网复制了下面的Ruby代码,并做了一些修改。

#insert code here 

但它不工作!

请帮忙。 我能做些什么来自己debugging程序?

使用Pry ( GitHub )。

安装通过:

 $ gem install pry $ pry 

然后添加:

 require 'pry' 

进入你的程序。

  1. 在Ruby中:

     ruby -rdebug myscript.rb 

    然后,

    • b <line> :放置断点
    • n(ext)s(tep)c(ontinue)
    • p(uts)显示

    (如perldebugging)

  2. 在Rails中:使用启动服务器

     script/server --debugger 

    并在代码中添加debugger

由于build议:使用撬! 我只能同意这一点。

pry比irb好得多。

你需要添加

 require 'pry' 

到您的源文件,然后通过添加在您的源代码中插入一个断点

 binding.pry 

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

一旦你的程序击中了

 binding.pry 

行,你将被直接投入到pry repl中,所有程序的上下文都在手边,这样你就可以简单地探索周围的事物,调查所有对象,改变状态,甚至可以随时更改代码。

我相信你不能改变你当前所使用的方法的代码,所以你可以悲伤地不改变下一行来执行。 但好的ruby代码往往是单线无论如何;-)

  1. 尽可能打印出variables。 (这叫做printfdebugging)你可以通过运行来完成

     STDERR.puts x.inspect 

    要么

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

    如果你想使这个更容易打字,那么你可能想使用例外gem。

  2. 打开警告。 如果你正在运行ruby然后运行-w开关(例如ruby -w script.rb )。 如果你是从irb运行的,而且你在1.9.2之前使用的是ruby版本,那么在会话开始时input$VERBOSE = true 。 如果你拼错一个实例variables,一旦发生警告,你会得到

    警告:实例variables@valeus未初始化

  3. 了解二元印章的概念(以下引用来自敏捷开发人员的实践 )

    把问题空间分成两半,看看哪一半存在问题。 然后再把这一半分成两半,重复一遍。

  4. 如果你用二元印章取得成功,你可能会发现有一行不符合你的期望。 例如

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

    即使你认为它会返回true ,也会给出false的值。 在这种情况下,您可能需要查看文档。 文档的网站包括ruby-doc.org或APIdock 。 在后一种情况下,你可以inputinclude? 在右上angular附近的放大镜旁边,selectinclude? 在它下面有Array (如果你不知道什么类[1, 2, 3] ,请在irb中input[1, 2, 3].class ),然后你可以包含? (数组) ,它描述了它的function。

    但是,如果文档没有帮助,那么如果您可以提出一个问题,那就是如果某个特定的行不是应该做的,而不是为什么整个脚本没有做到这应该。

通过引发exception进行debugging要比通过print日志语句进行眯眼更容易 ,而对于大多数错误来说,通常比打开byebugbyebug等irbdebugging器要快得多 。 这些工具不应该是你的第一步。


快速debuggingRuby / Rails:

1.快速方法:然后提出Exception.inspect其结果

debuggingRuby(尤其是Rails)代码的最快方法是在调用.inspect方法或对象(例如foo )时.inspect代码执行path中的exception:

 raise foo.inspect 

在上面的代码中, raise触发器会暂停执行代码Exception ,并返回一个错误消息,该消息便于包含有关正在尝试debugging的行上的对象/方法(例如foo )的.inspect信息。

这种技术对于快速检查一个对象或方法( 例如是否nil )以及立即确认一行代码是否在给定的上下文中甚至得到执行是有用的。

2.回退:使用像byebugbyebug ruby IRBdebugging器

只有在获得有关代码状态的信息之后,才能考虑转移到ruby gem irbdebugging器(如byebugbyebug ,以便更深入地了解执行path中的对象状态。


一般初学者build议

当你试图debugging一个问题,好的build议是总是: 阅读!@#$ ing错误消息(RTFM)

这意味着在行动之前仔细阅读错误信息,以便您了解要告诉您的内容。 当您进行debugging时,请在阅读错误消息时按照以下顺序询问以下精神问题:

  1. 什么的错误参考? (即,我有正确的对象类或是我的对象nil
  2. 什么方法的错误参考? (即它们是方法中的一个types;我可以在这种types的对象上调用这个方法吗?
  3. 最后,根据我最后两个问题的推断,我应该调查哪些代码行 ? (请记住:堆栈跟踪中的最后一行代码并不一定是问题所在)。

在堆栈跟踪中,要特别注意来自项目的代码行(例如,如果您使用的是Rails,则以app/...开始的行)。 99%的问题是你自己的代码。


为了说明为什么按照这个顺序解释是重要的…

例如,一个Ruby错误消息混淆了许多初学者:

你执行的代码在某些时候执行如下:

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

你会得到一个错误,指出:

undefined method "bar" for Nil:nilClass

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

for Nil:nilClass

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

不幸的是,由于这个错误是如何写入的( undefined method "bar" for Nil:nilClass ),很容易被误认为这个错误与bar undefined 。 如果没有仔细阅读,这个错误会导致初学者误以为Foobar方法的细节,完全错过了提示对象是错误类的错误部分(在这种情况下:nil)。 这是一个错误,通过阅读整个错误消息很容易避免。

概要:

开始任何debugging之前,请仔细阅读整个错误消息 。 这意味着: 开始探测到任何您认为可能发生错误的堆栈跟踪或代码行之前,请首先在错误消息中检查对象的types,然后检查其方法 。 这5秒钟可以节省5小时的挫折。

tl; dr:不要在打印日志中斜视:反而会引发exception。 在debugging前仔细阅读错误避免出现兔子漏洞。

所有其他的答案已经给了几乎所有的东西…只是一点点。

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

它的文档非常简单,请点击链接并查看。 简而言之,它允许您在编辑器中的当前行设置断点,在暂停时在漂亮的窗口中查看局部variables,跨越/进入 – 几乎所有常见的debugging器function。

对我来说,使用这个vimdebugging器来debuggingRails应用程序是相当愉快的,尽pipeRails 丰富的logging器function几乎消除了对它的需要。

  1. 您可以一路打印出您的variables
  2. 打开-w (警告)标志
  3. 使用诸如ruby-debug之类的工具

我强烈推荐这个video,以便select正确的工具来debugging我们的代码。

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

就我个人而言,我会重点介绍这个video中的两大主题。

  • 撬debugging数据真棒,“撬是一个数据浏览器”(原文如此)
  • debugging器似乎更好地逐步debugging。

那是我的两分钱!

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

https://github.com/deivid-rodriguez/pry-byebug

 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. 

要轻松debuggingRuby shell脚本,只需将其第一行改为:

 #!/usr/bin/env ruby 

至:

 #!/usr/bin/env ruby -rdebug 

然后每次显示debugging器控制台时,都可以select:

  • c继续(到下一个exception,断点或行: debugger ),
  • n为下一行,
  • w /显示帧/调用堆栈,
  • l显示当前的代码,
  • cat显示catchpoints。
  • h获取更多帮助。

另请参见: 使用ruby-debug进行debugging , ruby-debug gem的快捷键 。


如果脚本挂起 ,你需要回溯,请尝试使用lldb / gdb如:

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

然后检查你的过程前景。

gdbreplacelldb如果效果更好。 用sudo前缀来debugging非拥有的进程。

printfdebugging

关于debugging技术一直存在争议,一些人喜欢用打印语句进行debugging,还有一些人喜欢用debugging器深入挖掘。

我build议你尝试两种方法。

实际上最近有一位老Unix的人说,在某些时候printfdebugging是一个更快的方法。

但是如果你在某个工作上是新手,并且需要了解大量的代码,那么在这里一步一步地实现一些断点是非常有用的,并且如何工作。

它应该给你一些理解代码是如何编织的。

如果你是一些其他人的软件新手,它可能会帮助你跨过那里。

你会很快发现,如果他们安排在聪明的方式,或者如果这只是一堆狗屎。

从Ruby 2.4.0开始,在任何Ruby程序的中间启动一个IRB REPL会话是比较容易的。 把这些行放在你想要debugging的程序中:

 require 'irb' binding.irb 

您可以运行Ruby代码并打印出本地variables。 inputCtrl + D或quit以结束REPL并让Ruby程序继续运行。

您也可以使用putsp在程序运行时打印出来。

删除所有的东西

欢迎来到2017 ^ _ ^

好吧,如果你不反对尝试一个新的IDE,你可以免费做以下事情。

快速说明

  1. 安装vscode
  2. 如果你还没有安装Ruby开发工具包
  3. 为vscode安装Ruby,ruby-linter和ruby-rubocop扩展
  4. 手动安装任何gem rubyide / vscode-ruby指定的 ,如果需要的话
  5. launch.jsonconfiguration为使用{workspaceRoot}macros使用"cwd""program"字段
  6. 添加一个名为"showDebuggerOutput"的字段并将其设置为true
  7. 在“Debug”偏好设置中的任何位置启用"debug.allowBreakpointsEverywhere": true断点"debug.allowBreakpointsEverywhere": true

详细说明

  1. 下载Visual Studio Code又名vscode ; 这与Visual Studio不一样。 它是免费的,重量轻,并且通常是积极的。
  2. 安装Ruby开发工具包; 你应该按照他们在这里的回购说明: https : //github.com/oneclick/rubyinstaller/wiki/Development-Kit
  3. 接下来,您可以通过Web浏览器安装扩展程序,也可以在IDE中安装扩展程序 这是在IDE内部。 如果你select其他,你可以去这里 。 导航到vscode的扩展部分; 你可以用几种方法做到这一点,但是最有前途的方法可能会碰到F1 ,然后inpute x t直到出现一个名为Extensions:Install Extensions的选项。 替代方法是Ctrl Shift x和顶部菜单栏View->Extensions
  4. 接下来,您将需要以下扩展; 这些不是100%必要的,但是我会让你决定在做些什么之后要保留什么:
    • ruby; 延伸作者彭吕
    • rubyrubocop; 扩展作者misogi
    • ruby棉短绒; 扩展作者Cody Hoover
  5. 在ruby脚本的目录中,我们将通过名为.vscode命令行创build一个目录,在那里我们只需要一个名为launch.json的文件,在那里我们将存储一些configuration选项。
    • launch.json内容

{ "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. 你可能希望有能力把断点放在任何你喜欢的地方; 没有启用此选项可能会导致混淆。 要做到这一点,我们将进入顶部的菜单栏,并selectFile->Preferences->Settings (或Ctrl ),并滚动,直到到达Debug部分。 展开它并查找名为"debug.allowBreakpointsEverywhere"的字段 – select该字段,然后单击小铅笔图标并将其设置为true

在做了所有有趣的事情之后,您应该能够在类似于2017年中期的菜单中设置断点和debugging,并且可以使用较暗的主题: 在这里输入图像描述 与所有有趣的东西,如你的调用堆栈,可变查看器等

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

所有debugging器的母亲都是普通的老式的打印屏幕。 大多数时候,你可能只想检查一些简单的对象,一个简单快捷的方法就是这样:

 @result = fetch_result p "--------------------------" p @result 

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

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

我发现这对于我的90%的用例是有效的。 你也可以使用ruby-debug,但是我发现它大部分时间是过度的。

那么,ruby标准库有一个易于使用的类似gdb的控制台debugging器: http : //ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/DEBUGGER__.html不需要安装任何额外的gem。 Rails脚本也可以这样debugging。

例如

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

使用自然命令进行rubydebugging的stream程,包括next的块,按名称进入函数:

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

在这里输入图像描述

如果您使用的是RubyMine ,那么debuggingruby脚本非常简单直接。

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

1.设置断点

在第6行设置一个断点如下。

在这里输入图像描述

2.开始debugging

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

在这里输入图像描述

在这里输入图像描述

3.检查variables等

然后当执行命中一个断点时,你将能够检查variables等

在这里输入图像描述

更多信息供您参考

  1. 如果您想使用RubyMine进行远程debugging ,可以这样做。
  2. 如果您想使用RubyMine远程debuggingdocker中运行的rails ,这也很简单。