【问题标题】:Why do I get "stack level too deep" from method_missing in irb 1.9.3?为什么我从 irb 1.9.3 中的 method_missing 得到“堆栈级别太深”?
【发布时间】:2012-03-18 11:41:04
【问题描述】:

场景:

-bash-3.2$ irb -f
ruby-1.9.3-p0 :001 > @v = {}
 => {} 
ruby-1.9.3-p0 :002 > def method_missing(sym, *args); @v[sym]; end
 => nil 
ruby-1.9.3-p0 :003 > a
(irb):2: stack level too deep (SystemStackError)
-bash-3.2$ 

我使用 -f 运行以避免加载任何 irbrc 内容。 当我输入a 时,我希望得到 nil。发生了什么,是否有解决方法?我尝试用begin/rescue Exception 块包装a,但这并没有做任何事情。

这也发生在 1.9.2,但不是 1.9.1。

更奇怪的行为:

-bash-3.2$ irb -f
irb(main):001:0> @v = {}
=> {}
irb(main):002:0> def method_missing(sym, *args); @v[sym]; end; 5.times { p a }
nil
nil
nil
nil
nil
=> 5
irb(main):003:0> a
(irb):2: stack level too deep (SystemStackError)
-bash-3.2$ 

这告诉我 irb 中存在错误,或者 ruby​​ 中的一些模糊错误被 irb 触发。另外,在定义了method_missing之后,即使存在local_variableseval这样的方法也会导致错误。

【问题讨论】:

  • 在 IRB 下定义 method_missing 时出现各种错误,这些错误不会在 IRB 之外发生。例如:irb> def method_missing(*a); p a; end; => nil; [:to_hash]; [:to_str]; C:/Ruby/lib/ruby/site_ruby/1.9.1/readline.rb:45:in raise: can't convert TypeError to String (TypeError#to_str gives Array) (TypeError)
  • 随机猜测(不是答案):irb 依靠现有的 monkeypatch 到 method_missing,重新定义它会搞砸。 This 看起来有点相关。
  • @Phrogz 那个错误报告有点有趣。但我认为它不适用于这种情况。

标签: ruby irb method-missing


【解决方案1】:

看起来像将其定义为单例方法一样有效:

def self.method_missing(sym, *args); @v[sym]; end

将其定义为顶级方法取代了 BasicObject#method_missing,这可能影响了 Phrogz 所说的一些 irb 内部结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 2013-10-05
    • 2011-11-17
    • 2012-07-24
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多