为什么我会从 irb 1.9.3 中的method_missing获得"stack level too deep"?



场景:

-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时,我期望得到零。发生了什么,有解决办法吗?我尝试用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中有一个bug,或者ruby中的一些模糊bug是由irb触发的。此外,在定义method_missing之后,即使是像local_variableseval这样存在的方法也会导致错误。

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

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

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

最新更新