关于调试:如何调试Ruby脚本?

How do I debug Ruby scripts?

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

但它不起作用!

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


Use Pry(Github).

Install via:

1
2
$ gem install pry
$ pry

Then add:

1
require 'pry'

进入你的程序。


  • In Ruby:

    1
    ruby -rdebug myscript.rb

    然后

    • 中断点
    • 第十五届会议
    • 用于显示

    就像珍珠般

  • 在轨道上:与

    1
    script/server --debugger

    在《守则》中。


  • 如栏杆建议:使用撬棍!我只能同意这一点。

    Pry是一个比IRB更好的repl。

    你需要添加

    1
    require 'pry'

    到源文件然后通过添加

    1
    binding.pry

    在你想看东西的地方(这类似于在经典的IDE环境中触发断点)

    一旦你的程序点击

    1
    binding.pry

    行,你会被扔到撬锁里,所有程序的上下文都在手边,这样你就可以简单地探索周围的一切,调查所有的物体,更改状态,甚至可以动态更改代码。

    我相信你不能改变你目前所处方法的代码,所以很遗憾,您不能更改要执行的下一行。但是好的Ruby代码通常都是单行的;-)


    通过引发异常进行调试要比通过print日志语句进行调试容易得多,而且对于大多数bug来说,它通常比打开像prybyebug这样的IRB调试器快得多。这些工具不应该是你的第一步。好的。快速调试Ruby/Rails:1。快速方法:先提出一个Exception,再提出一个.inspect的结果。

    调试Ruby(尤其是Rails)代码的最快方法是对raise进行调试,这是在对方法或对象(例如foo调用.inspect时沿着代码的执行路径发生的异常:好的。

    1
    raise foo.inspect

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

    这种技术有助于快速检查对象或方法(例如,它是nil吗?)并立即确认某一行代码是否在给定的上下文中执行。好的。2。回退:使用RubyIRB调试器,如byebugpry

    只有在您获得了关于代码执行流状态的信息之后,您才应该考虑移动到Ruby gem IRB调试器,如prybyebug,在那里您可以更深入地了解执行路径中对象的状态。好的。一般初学者建议

    当您试图调试一个问题时,最好的建议是:始终阅读!@#$ing错误消息(RTFM)好的。

    这意味着在采取行动之前要仔细、完整地阅读错误消息,以便您理解它试图告诉您什么。调试时,在读取错误消息时,按此顺序提出以下心理问题:好的。

  • 错误引用了什么类?(即,我是否有正确的对象类,或者我的对象是nil)
  • 错误引用了什么方法?(即,它们是方法中的A类型;我可以对此类型/对象类调用此方法吗?)
  • 最后,使用我从最后两个问题中推断出的内容,我应该研究哪些代码行?(请记住:堆栈跟踪中的最后一行代码不一定是问题所在。)
  • 在堆栈跟踪中,请特别注意来自项目的代码行(例如,如果您使用的是Rails,则从app/...开始的行)。99%的时候问题出在你自己的代码上。好的。

    为了说明为什么按这个顺序解释很重要…好的。例如,让许多初学者感到困惑的Ruby错误消息:

    您执行的代码在某个时刻执行如下:好的。

    1
    2
    3
    4
    5
    @foo = Foo.new

    ...

    @foo.bar

    你会得到一个错误,说明:好的。

    undefined method"bar" for Nil:nilClass好的。

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

    for Nil:nilClass好的。

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

    不幸的是,由于这个错误是如何写入的(undefined method"bar" for Nil:nilClass),很容易被欺骗认为这个错误与barundefined有关。当不仔细阅读时,这个错误会导致初学者错误地去挖掘Foobar方法的细节,完全忽略了暗示对象属于错误类的错误部分(在本例中为零)。这是一个很容易通过阅读错误消息来避免的错误。好的。

    总结:好的。

    在开始任何调试之前,请务必仔细阅读整个错误消息。这意味着:在开始对任何stacktrace或您认为可能发生错误的代码行进行重新授权之前,始终先检查错误消息中对象的类类型,然后检查其方法。这5秒钟可以帮你节省5个小时的沮丧。好的。

    tl;dr:不要斜视打印日志:而是引发异常。调试前仔细阅读错误,避免出现兔子洞。好的。好啊。


  • 在可能的情况下打印变量。(这叫打印解调)你可以通过运行

    1
    STDERR.puts x.inspect

    黄金

    ZZU1

    如果你想让这个简单的类型,那么你可以使用这个模型GEM。

  • 转向警报如果你是ruby的运行,那就用-w开关(EG EDOCX1〕〔2〕运行。如果你是从IRB运行的,那么在会议开始时,你会使用1.9.2型Ruby Prior的版本。如果你错过了一个可变的程序,你会得到一次温暖。

    warning: instance variable @valeus not initialized

  • 理解二进制选择的概念(跟随Quote的是一个敏捷的发展者的实践)

    BLCK1/

  • 如果你成功了一个二进制选择,你可能会发现,有一条单一的线路你不希望做的事情。举例来说

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

    给我一个false的价值,即使你认为这是回报true。在这种情况下,你可能想看文件。Web sites for documentation include Ruby-doc.org,or Apidock.下面的例子,你是EDOCX1型〔6〕下一个在最右角的大玻璃上,选择include?下一个,如果你不知道Array下一个是什么(Array),which describes what it does.

    但是,如果文献不起作用,如果你能问一个问题,一条特定的线路不应该做什么,那你就更愿意得到一个好的答案。


  • 删除所有内容

    欢迎来到2017年^^

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

    快速指示

  • 安装VSCODE
  • 如果您还没有安装Ruby开发工具包
  • 为vscode安装ruby、ruby linter和ruby rubocop扩展
  • 如果需要,手动安装gems rubyide/vscode ruby指定的任何程序
  • 使用{workspaceRoot}宏将launch.json配置为使用"cwd""program"字段。
  • 添加一个名为"showDebuggerOutput"的字段,并将其设置为true
  • 在调试首选项中的任意位置启用断点,如"debug.allowBreakpointsEverywhere": true
  • 详细说明

  • 下载Visual Studio代码aka vscode;这与Visual Studio不同。它是免费的,重量轻,而且被普遍看好。
  • 安装Ruby开发工具包;您应该按照他们报告中的说明操作:https://github.com/oneclick/rubyinstaller/wiki/development-kit
  • 接下来,您可以通过Web浏览器安装扩展,也可以在IDE内部安装扩展;这是在IDE内部进行的。如果你选择另一个,你可以到这里来。导航到vscode的扩展部分;您可以用两种方法来实现这一点,但最适合未来使用的方法可能是点击f1,然后键入eykbdxkbdxkbdxkbdxkbdbdbkbd,直到有一个名为扩展:安装扩展的选项可用为止。备选方案是ctrlxkbdxkbdshiftx,从顶部菜单栏,View->Extensions中选择。
  • 接下来,您将需要以下扩展;这些扩展不是100%必需的,但是在您修补了一些扩展之后,我将让您决定保留什么:
    • Ruby;扩展作者彭吕
    • ruby rubocop;扩展作者misogi
    • Ruby Linter;扩展作者Cody Hoover
  • 在Ruby脚本的目录中,我们将通过名为.vscode的命令行创建一个目录,在这里我们只需要一个名为launch.json的文件,我们将在其中存储一些配置选项。
    • 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
    }
    ]
    }

  • 按照扩展作者的说明手动安装gem。它现在位于这里:https://github.com/rubyide/vscode ruby安装ruby依赖项
  • 您可能希望能够在任何需要的地方放置断点;如果不启用此选项,可能会导致混淆。为此,我们将转到顶部菜单栏,选择File->Preferences->Settings(或ctrl),滚动到Debug部分。展开它并查找一个名为"debug.allowBreakpointsEverywhere"的字段—选择该字段并单击小铅笔外观图标并将其设置为true
  • 在做了所有有趣的事情之后,您应该能够在类似于2017年年中的菜单中设置断点和调试,以及更黑暗的主题:enter image description here,其中包含所有有趣的事情,如调用堆栈、变量查看器等。

    最大的pita是1)安装pre-req和2)记住配置.vscode\launch.json文件。只有2可以为将来的项目添加任何负担,您只需复制一个足够通用的配置,如上面列出的配置。可能有一个更一般的配置位置,但我不知道我的头。


    所有其他的答案都会付出一切只是一个小帐单。

    如果你想要更多的ID-Like Debugger(non-cli)并且不害怕使用VIM作为编辑,我建议VIM Ruby Debugger plugin for it.

    它的文献很漂亮,所以跟着链接看。简而言之,它允许您在编辑器中设置当前线上的断点,在牛窗中的视图局部变量在暂停,在/至少在所有常见的解调特性。

    对我来说,这是一个很好的开关,用它来开启一个铁路应用程序,尽管铁路的丰富测井能力最能消除对它的需要。


    我刚刚发现了这个gem(将proy变成mri Ruby 2.0+的调试器)

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

    1
    2
    3
    4
    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.

  • 你可以沿着这条路打印变量。
  • 转向爱德华王子岛
  • 使用一个工具,如红宝石

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

    https://www.youtube.com/watch?V= GWGF8GCYNV0

    就我个人而言,我会在这段视频中突出两大主题。

    • 对调试数据来说,Pry非常棒,"Pry是一个数据浏览器"(sic)
    • 调试程序似乎更适合逐步调试。

    那是我的两分钱!


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

    1
    #!/usr/bin/env ruby

    到:

    1
    #!/usr/bin/env ruby -rdebug

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

    • 用于continue的c(到下一个异常、断点或行:debugger)
    • n用于下一行,
    • w/where显示帧/调用堆栈,
    • l显示当前代码,
    • cat显示了一些要点。
    • h寻求更多帮助。

    另请参见:用Ruby调试,Ruby调试gem的快捷键。

    如果脚本挂起而您需要回溯,请尝试使用lldb/gdb,如下所示:

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

    然后检查您的进程前景。

    如果效果更好,用gdb替换lldb。前缀为sudo,用于调试非自有进程。


    从Ruby2.4.0开始,在任何Ruby程序的中间启动IRBRepl会话都比较容易。将这些行放在要调试的程序中的点上:

    1
    2
    require 'irb'
    binding.irb

    您可以运行Ruby代码并打印出局部变量。键入ctrl+d或quit结束repl并让ruby程序继续运行。

    您还可以使用putsp在程序运行时打印出其值。


    如果您正在使用RubyMine,调试Ruby脚本是简单而简单的。

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

    1。设置断点

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

    enter image description here

    2。开始调试

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

    enter image description here

    enter image description here

    三。检查变量等。

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

    enter image description here

    更多信息供您参考

  • 如果您想使用Rubymine进行远程调试,可以这样做。
  • 如果您想使用Rubymine来远程调试在Docker中运行的Rails,也很简单。

  • 好吧,Ruby Standard lib有一个易于使用的类似gdb的控制台调试器:http://ruby-doc.org/stdlib-2.1.0/libdoc/debug/rdoc/debugger_uuu.html不需要安装任何额外的宝石。Rails脚本也可以这样调试。

    例如

    1
    2
    3
    4
    def say(word)
      require 'debug'
      puts word
    end

    printf调试

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

    我建议你尝试两种方法。

    事实上,最近一个老Unix的人说,在某些情况下,printf调试对他来说是一种更快的方法。

    但是如果你是新来的,需要理解一大堆代码,那么,在那里走来走去真的很有用,在这里和那里放置一些断点,和它一起工作。

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

    如果你对其他人的软件不熟悉,它可能会帮助你跨过那里。

    你很快就会知道他们是否安排得很巧妙,或者如果那只是一堆狗屎。


    所有调度员的母亲都是平原老印刷的屏幕。在大多数时间里,你可能只想检查一些简单的物体,一个快捷而简单的方式是这样的:

    1
    2
    3
    4
    @result = fetch_result

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

    这将打印出@result到stdout的内容,前面有一条线路,以便容易识别。

    如果你使用一个能像铁路那样运行的框架,你甚至不需要保留你的应用程序。(Unless the code you are debugging is not reloaded to framework specific settings)

    我找到这本书的90%的用户名是我的。你也可以用红宝石解开,但我发现它在大部分时间里已经过时了。


    有许多具有不同功能的调试器,您可以根据它们进行选择。我的首要任务是满足于撬动,即:

    • 关于如何使用的快速可理解信息
    • 直观的步骤(例如,轻松进入区块)
    • "后退"(撬动部分满足需要)