这不是特定于 Ruby 的行话。大多数调试都很常见。
关于堆栈帧
您可能已经看到堆栈跟踪:
/usr/local/rvm/gems/ree-1.8.7-2010.02/gems/redgreen-1.2.2/lib/redgreen.rb:28:in `write': Broken pipe (Errno::EPIPE)
from /usr/local/rvm/gems/ree-1.8.7-2010.02/gems/redgreen-1.2.2/lib/redgreen.rb:28:in `output_single'
from /usr/local/rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:72:in `add_fault'
from /usr/local/rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:70:in `to_proc'
from /usr/local/rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/test/unit/util/observable.rb:78:in `call'
完整的跟踪向您显示“调用堆栈”。顶部的行是引发异常的位置,它下面的行显示了程序到达该点所经过的代码路径。这些行中的每一行都是堆栈中的一个级别,称为“堆栈帧”。因此,当抛出异常时,当前堆栈帧是堆栈的顶部。如果你搬到frame -1
然后您将移至调用堆栈的底部。把调用栈想象成一堆盘子。当你调用一个函数时,你将一个盘子添加到堆栈中,当你从那个函数返回时,你从堆栈中删除一个盘子。每个盘子都是一个框架。由于您通常最终在函数内的函数内调用函数,因此您最终会得到相当深的调用堆栈,并且在调试中上下遍历它们可能很有用,以评估调用堆栈中每个点的局部变量和状态。
如果您想了解更多关于调用堆栈的信息,维基百科有一篇不错的文章。
关于线程
大多数现代编程语言都是多线程的,这意味着它们可以(几乎)同时执行多个代码路径。因此,例如,假设您有一个可视化应用程序,并且您执行一些昂贵的计算。当计算正在运行时,您的 GUI 将无法对任何用户输入做出反应,这使得应用程序对用户来说似乎被冻结了。您可以通过运行两个线程来解决这个问题:一个线程负责接受和处理用户输入并绘制 GUI,另一个线程负责进行繁重的计算。您的计算线程可能会陷入昂贵的循环中,并且您的 GUI 线程将继续运行并绘制 GUI。
如果您正在运行多线程应用程序,那么您必须选择要在哪个线程中评估您的调试命令(表达式),因为每个线程将位于代码的不同点,并且将具有不同的调用堆栈和不同的局部变量和状态等。这是评估上下文。
但是,我注意到这是一个 Rails 问题,并且 Rails(默认情况下)是单线程的,因此您不必担心线程。