我从互联网上复制了以下Ruby代码,并进行了一些更改,但它无法正常工作。
我该如何自行调试程序?
通过以下方式进行安装:
$ gem install pry
$ pry
然后添加:require 'pry'; binding.pry
然而,在pry
0.12.2中,没有像next
、break
这样的导航命令。一些其他的gems也提供了这个功能,例如pry-byebug
。
binding.pry
一样简单。它还带有颜色自动完成、文档查找和动态编辑以及重新加载方法的功能。 - Andrea FiorePry
和byebug
都很好,但不是你调试的第一步。在大多数情况下,使用raise object.inspect
引发异常比打开irb会话更快地解决你的问题。我建议只有在更简单的解决方案(如引发异常)无法解决问题时才使用控制台调试器。 - Kelsey Hannanpry
逐行调试代码?我找不到如何实现;这是我对于一个调试器的期望。 - jpetazzo在 Ruby 中:
ruby -rdebug myscript.rb
然后,
b <line>
:设置断点n(ext)
或s(tep)
和c(ontinue)
p(uts)
用于显示(类似于perl调试)
在Rails中:使用以下命令启动服务器
script/server --debugger
在代码中添加debugger
。
facets
的Rails 2.2应用程序上运行,并且没有成功。对于古老的Rails应用程序,ruby-debug
有些棘手但可以完成工作。 - Abe Voelker如Banister所建议的:使用pry!我完全同意。
Pry比IRB更好用,这点毋庸置疑。
您需要添加:
require 'pry'
将其添加到您的源文件中,
然后通过在源代码中添加断点来调试。
binding.pry
在您想查看事物的地方 (这就像在经典IDE环境中触发断点)
一旦您的程序命中
binding.pry
你将被抛入pry repl中,直接拥有程序的所有上下文, 这样你就能够轻松地探索周围的一切、调查所有对象、改变状态,甚至动态修改代码。
我相信你不能更改当前所在方法的代码, 因此你无法悲伤地改变下一行要执行的代码。 但好的 Ruby 代码通常都是单行的;-)
通过抛出异常来调试 比通过阅读 print
日志语句更容易,并且对于大多数错误,它通常比打开像 pry
或 byebug
这样的 irb 调试器快得多。这些工具不应始终是您的第一步。
Exception
然后使用 .inspect
查看其结果调试 Ruby(尤其是 Rails)代码最快的方法是在调用方法或对象(例如 foo
)时沿着代码执行路径抛出异常并同时调用 .inspect
。
raise foo.inspect
在上面的代码中,raise
引发一个Exception
,它会停止代码的执行,并返回一个错误消息,其中包含关于你正在尝试调试的行上的对象/方法(即foo
)的.inspect
信息。这种技巧对于快速检查对象或方法(例如,它是否为nil
?)以及立即确认给定上下文中是否执行了一行代码非常有用。
byebug
或pry
pry
或byebug
这样的ruby gem irb调试器,从而可以更深入地研究执行路径中的对象状态。
nil
?)app/...
开头的行)。99%的时间,问题出现在您自己的代码中。
@foo = Foo.new
...
@foo.bar
如果你收到以下错误信息:
undefined method "bar" for Nil:nilClass
初学者看到这个错误会认为问题在于方法bar
未定义。但事实并非如此。实际上,这个错误中真正重要的部分是:
for Nil:nilClass
for Nil:nilClass
意味着@foo
是空值(Nil)! @foo
不是Foo
实例变量!你有一个空值对象。当你看到这个错误时,它只是Ruby想告诉你方法bar
不存在于空值(Nil)类的对象中(好吧!因为我们试图使用Foo
而不是Nil
类的对象的方法)。
不幸的是,由于这个错误的表述方式(undefined method "bar" for Nil:nilClass
),很容易让人误以为这个错误与bar
未定义有关。如果没有仔细阅读,这个错误会导致初学者错误地深入研究Foo
的bar
方法的细节,完全忽略了错误提示对象是错误的类(在这种情况下:空值)的部分。仔细阅读错误消息可以轻松避免这种错误。
总结:
在开始任何调试之前,始终仔细阅读完整的错误消息。这意味着:始终先检查错误消息中对象的类类型,然后是其方法,在你开始深入研究可能发生错误的堆栈跟踪或代码行之前。花上5秒钟可以为你节省5个小时的挫败感。
简明扼要:不要盯着打印日志看:引发异常或使用irb调试器。在调试之前仔细阅读错误信息,避免陷入死胡同。
尽可能地输出变量内容进行调试。(这被称为 printf 调试)。您可以通过运行以下代码实现:
STDERR.puts x.inspect
或者STDERR.puts "Variable x is #{x.inspect}"
如果您想要更容易地输入代码,那么您可能想使用exemplor gem。打开警告。如果您正在运行ruby,则使用-w
开关运行它(例如ruby -w script.rb
)。如果您在irb中运行它,并且您使用的是1.9.2之前的版本,请在会话开始时键入$VERBOSE=true
。如果您拼错了一个实例变量,一旦警告打开,您将收到以下提示:
warning: instance variable
@valeus
not initialized
理解二分查找的概念(以下引用来自Practices of an Agile Developer)
将问题空间划分为两半,并查看哪一半包含问题。然后再将该半部分分成两半,并重复此过程。
如果您对二分查找成功,您可能会发现有一行代码没有按照您的预期执行。例如:
[1, 2, 3].include?([1,2])
即使你认为它应该返回true
,但其实它的值是false
。在这种情况下,你可能需要查看文档。文档网站包括ruby-doc.org或者APIdock。对于后一种情况,你可以在右上角放大镜旁边输入include?
,选择其下方带有Array
的include?
(如果你不知道[1, 2, 3]
是什么类别,请在irb中输入[1, 2, 3].class
),然后你会进入到include? (Array)
,其中详细介绍了它的功能。
然而,如果文档无法帮助你,你最好能够提出一个具体行为有问题的问题,而非询问整个脚本出现了什么问题。
https://github.com/deivid-rodriguez/pry-byebug
gem install pry-byebug
然后像使用pry
一样使用它,在你想要中断的那一行进行标记:
require 'pry'; binding.pry
与普通的pry不同,这个gem具有一些关键的类似于GDB的导航命令,例如next
,step
和break
:
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.
#!/usr/bin/env ruby
至:
#!/usr/bin/env ruby -rdebug
每次调试控制台出现时,您可以选择:
c
表示继续执行(到下一个异常、断点或带有debugger
的行),n
表示执行下一行,w
/where
表示显示框架/调用堆栈,l
表示显示当前代码,cat
表示显示catchpoints。h
表示更多帮助。另请参见:使用ruby-debug进行调试, ruby-debug gem的快捷键。
如果脚本只是挂起,并且您需要回溯,请尝试使用lldb
/gdb
,例如:
echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -nf ruby)
然后检查你的进程前台。
如果效果更好,将lldb
替换为gdb
。在非所属进程上调试时,请加前缀sudo
。
所有其他答案已经几乎给出了一切...只是稍作补充。
如果您想要一些更类似于IDE的调试器(非CLI),并且不害怕使用Vim作为编辑器,我建议您使用Vim Ruby Debugger插件。
它的文档非常简单明了,所以请跟随链接查看。简而言之,它允许您在编辑器中设置当前行的断点,在暂停时在漂亮的窗口中查看本地变量,进行步进/转至 - 几乎所有通常的调试器功能。
对我来说,使用这个vim调试器为调试Rails应用程序非常愉快,尽管Rails的丰富的记录器能力几乎消除了对它的需求。
删除所有的东西
欢迎来到2017年 ^_^
好的,如果你不反对尝试一个新的IDE,你可以免费地按照以下步骤进行。
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": "本地文件调试",
"type":"Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "{workspaceRoot}/../script_name.rb",
"args": [],
"showDebuggerOutput": true
}
]
}
文件->首选项->设置
(或 Ctrl,),然后滚动到 调试
部分。展开它并查找一个名为 "debug.allowBreakpointsEverywhere"
的字段——选择该字段并单击类似铅笔的小图标,将其设置为 true
。 .vscode \ launch.json
文件。只有#2应该为未来的项目增加任何负担,并且您可以复制一个足够通用的配置,例如上面列出的配置。可能有一个更一般的配置位置,但我不知道。https://www.youtube.com/watch?v=GwgF8GcynV0
个人而言,我认为这个视频涉及两个重要的主题。
以上是我的个人看法!
pry-byebug
和pry
来暂停、检查、继续执行、进入和退出方法,请查看我在类似问题中的回答。 - software_writer