我从互联网上复制了以下Ruby代码并进行了一些更改。
但它不起作用!
请帮忙。我可以做些什么来自己调试程序?
答案 0 :(得分:132)
答案 1 :(得分:110)
在Ruby中:
ruby -rdebug myscript.rb
然后,
b <line>
:put break-point n(ext)
或s(tep)
和c(ontinue)
p(uts)
用于显示(如perl调试)
在Rails中:使用
启动服务器script/server --debugger
并在代码中添加debugger
。
答案 2 :(得分:54)
栏杆推荐:使用撬! 我只能同意这一点。
pry是一个比irb更好的代表。
您需要添加
require 'pry'
到你的源文件 然后通过添加
在源代码中插入断点binding.pry
在你要看的东西的地方 (这就像在经典IDE环境中触发断点一样)
一旦你的节目点击了
binding.pry
一行,你会被扔进撬副本, 随着你的程序的所有上下文, 这样你就可以简单地探索周围的一切,调查所有物体, 改变状态,甚至动态改变代码。
我相信你无法改变你当前所处方法的代码, 所以你可以遗憾地不改变下一行要执行。 但无论如何,好的红宝石代码往往是单行; - )
答案 3 :(得分:28)
通过引发异常进行调试 比忽略print
日志语句更容易,对于大多数错误,它通常< em>快得多比打开像pry
或byebug
这样的irb调试器。这些工具不应该是你的第一步。
Exception
然后.inspect
结果调试Ruby(尤其是Rails)代码的最快方式是在代码的执行路径上raise
异常,同时在方法或对象上调用.inspect
(例如foo
):
raise foo.inspect
在上面的代码中, raise
会触发 Exception
停止执行代码,并返回在您尝试调试的行上方便地包含有关对象/方法(即.inspect
)的foo
信息的错误消息。
此技术对于快速检查对象或方法(例如是nil
?)以及立即确认代码行是否均匀非常有用在给定的上下文中完全执行。
byebug
或pry
只有在您获得有关代码执行流程状态的信息后,才应考虑转移到像pry
或byebug
这样的ruby gem irb调试器,您可以在其中深入研究对象的状态你的执行路径。
当您尝试调试问题时,建议总是: 阅读!@#$ ing错误消息(RTFM)
这意味着在执行操作之前,请仔细阅读 阅读错误信息时,以下心理问题按此顺序:
nil
?)在堆栈跟踪中,要特别注意来自项目的代码行(例如,如果使用Rails,则以app/...
开头的行)。 99%的时间问题出在你自己的代码上。
说明为什么按此顺序解释 很重要......
执行在某些时候执行的代码:
@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
有关。如果没有仔细阅读,这个错误会导致初学者错误地深入研究bar
上Foo
方法的详细信息,完全忽略了提示该对象属于错误类的错误部分(在此案例:无)。通过完整阅读错误消息可以轻松避免这种错误。
摘要:
在开始任何调试之前,请务必小心阅读整个错误消息。这意味着:请务必先在首先错误消息中检查对象的 类 类型,然后检查 方法 ,之前您开始调查任何您认为可能发生错误的堆栈跟踪或代码行。这5秒钟可以为你节省5个小时的挫折感。
tl; dr:不要斜视打印日志:改为引发异常。通过在调试之前仔细阅读错误来避免兔子洞。
答案 4 :(得分:19)
尽可能打印出变量。 (这称为printf调试)您可以通过运行
来完成此操作STDERR.puts x.inspect
或
STDERR.puts "Variable x is #{x.inspect}"
如果您想让这更容易打字,那么您可能想要使用exemplor gem。
打开警告。如果您正在运行ruby
,请使用-w
开关(例如ruby -w script.rb
)运行它。如果您是从irb运行它,并且在1.9.2之前使用的是ruby版本,请在会话开始时键入$VERBOSE = true
。如果拼错了一个实例变量,一旦出现警告,你就会得到
警告:实例变量
@valeus
未初始化
理解二元斩的概念(以下引用来自Practices of an Agile Developer)
将问题空间分成两半,看看哪一半包含问题。然后再将这一半分成两半,然后重复。
如果您使用二进制印章成功,您可能会发现有一行不符合您的预期。例如
[1, 2, 3].include?([1,2])
的值为false
,即使您认为它会返回true
。在这种情况下,您可能需要查看文档。文档的网站包括ruby-doc.org或APIdock。在后一种情况下,您在右上角附近的放大镜旁边键入include?
,选择其下方有include?
的{{1}}(如果您不知道哪个类Array
是,在irb中输入[1, 2, 3]
,然后转到include? (Array),其中描述了它的作用。
但是,如果文档没有帮助,如果您可以询问特定行如何不应该执行的操作,那么您更有可能得到一个好答案,而不是为什么整个脚本不是'做他们应该做的事。
答案 5 :(得分:7)
删除所有内容
欢迎来到2017 ^ _ ^
好的,如果您不反对尝试使用新的IDE,可以执行以下操作 free 。
launch.json
宏"cwd"
配置为使用"program"
和以及 {workspaceRoot}
字段
"showDebuggerOutput"
的字段并将其设置为true
"debug.allowBreakpointsEverywhere": true
vscode
;这与Visual Studio不同。它是免费的,重量轻的,并且通常都是积极的。View->Extensions
.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
}
]
}
File->Preferences->Settings
(或 Ctrl ,)并滚动,直至到达Debug
部分。展开它并查找名为"debug.allowBreakpointsEverywhere"
的字段 - 选择该字段并单击小铅笔图标并将其设置为true
。在完成所有有趣的事情之后,您应该能够在2017年中期的类似菜单中设置断点和调试以及更暗的主题:以及所有有趣的内容,例如调用堆栈,变量观众等。
最大的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)
-w
(警告)标记答案 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-debug,Key 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+的调试器)
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
就个人而言,我将在本视频中重点介绍两个重要主题。
那是我的两分钱!
答案 12 :(得分:3)
如果您使用的是RubyMine,则调试ruby脚本非常简单明了。
假设您有一个Ruby脚本hello_world.rb
在第6行设置断点,如下所示。
现在您可以启动调试器来运行脚本:
然后当执行到达断点时,您将能够检查变量等。
答案 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,即: