【问题标题】:Naming array method 'to_hash' causes 'stack level too deep' error命名数组方法“to_hash”导致“堆栈级别太深”错误
【发布时间】:2013-12-22 20:49:42
【问题描述】:

我尝试创建一个“to_hash”数组方法,但不断收到“堆栈级别太深”错误:

class Array
  def to_hash
    Hash[self.each_index.zip(self)]
  end
end

puts [50, 49, 53, 44].to_hash

# SystemStackError: stack level too deep

我终于发现是方法名称“to_hash”导致了问题。只需将其更改为 'to_hsh' 即可使其按预期工作:

class Array
  def to_hsh
    Hash[self.each_index.zip(self)]
  end
end

puts [50, 49, 53, 44].to_hsh

# => {0=>50, 1=>49, 2=>53, 3=>44}

如果我尝试在数组上调用“to_hash”方法(不编写自己的方法),我会得到:

NoMethodError: [50, 49, 53, 44]:Array 的未定义方法“to_hash”

那么,如果数组没有内置的“to_hash”方法,为什么我将自己的数组方法命名为“to_hash”会出现问题?

【问题讨论】:

  • “医生,我这样做这个会很痛” - “所以不要那样做”。你为什么要这样做?
  • 只是想明白。

标签: ruby


【解决方案1】:

因为Kernel#Hash 方法调用to_hash。这会导致递归调用。

文档说:

通过调用 arg.to_hash 将 arg 转换为 Hash。当 arg 为 nil 或 [] 时返回一个空的 Hash。

Hash[self.each_index.zip(self)] 行中,self.each_index.zip(self) 生成一个数组,Kernel#Hash 在其上调用to_hash。现在这个to_hash 变成了你自定义的to_hash 方法,它是一个递归调用,并且产生了stack level too deep (SystemStackError)的错误。

【讨论】:

  • 啊,谢谢你的解释!我只是在不使用 Hash[] 的情况下重写了 'to_hash' 方法,而且确实有效。
猜你喜欢
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
相关资源
最近更新 更多