在IRB中使用Ruby单例方法时堆栈溢出

时间:2013-02-09 14:02:08

标签: ruby irb

正如主题所述,在IRB中使用单例方法时,我遇到了堆栈溢出。以下是我尝试过的代码:

c= C.new
class << c
  def class
    "my class is #{self.class}."
  end
end

当我打电话给c.class时,我得到了一个:

SystemStackError: stack level too deep
Maybe IRB bug!

我找到了一个关于如何调整stack sizes的参考资料,但不了解首先是什么堆栈大小。

问题: 为什么我在IRB中收到错误?另外,我如何继续尝试使用Ruby单例/类方法?

4 个答案:

答案 0 :(得分:3)

首先,有一些叫做recursion的东西,函数可以调用它自己。这是您在代码中无意中完成的操作。

第二件事,堆栈是维护函数调用跟踪的东西。因此,当达到递归结束或堆栈级别深度时,它可以正确地恢复程序。

它是这样的: 假设您有功能A和功能B.

function A {
  /* some code */
  B()
  /* some more code */
}

function B {
  return / * something * /
}

你的机器基本上停止执行A,将A中的变量状态保存到堆栈中,调用并执行B.当最后B退出时,它从堆栈弹出并继续执行A.

在该具体示例中,因为您希望定义自己的class方法。以下代码应该:

def class
  "my class is #{super}"
end

希望这有帮助。

答案 1 :(得分:1)

您已为此对象创建了对象和已定义的方法class。然后在这个方法中你调用相同的方法class - 你有无限的递归。

这就是为什么在定义自己的方法时应该避免使用系统依赖关键字的原因,在您的示例中它可以是这样的:

class << c
  def klass
    "my class is #{self.class}"
  end
end

答案 2 :(得分:1)

堆栈源自计算机的内存模型。

每个节目都有heapstack。 堆部分现在不重要了。

当一个程序调用一个函数时,会发生一些事情。

  • 程序的当前位置放在堆栈上
  • 当前范围的变量放在堆栈上

当你离开一个函数时,这些动作以相反的顺序反转,以便在调用函数之前复制程序的状态。

因此,当你的函数调用它自己(它会这样做)时,它会将字符串“my class is”和当前的programm位置放在堆栈上并再次启动函数,这样做也是如此。

这会持续多次迭代,直到超过为程序保留的auf堆栈数量。 (这取决于您的操作系统,最终取决于可用的内存量,并且总是有限的。) 这是你得到这个例外的时候。系统通知您,它没有堆栈空间。

这通常只发生在没有停止条件的递归中。

答案 3 :(得分:0)

除了解释堆栈如何工作的所有好答案之外,

class是Ruby中的保留关键字。方法Object#class是一个独特的例外。你无法真正重新定义它。