2012-02-28 55 views
3

場景:爲什麼從irb 1.9.3的method_missing中得到「棧級太深」?

-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一個錯誤,或者在Ruby中一些不起眼的錯誤是由IRB觸發。而且,在定義method_missing之後,即使存在類似local_variableseval的方法也會導致錯誤。

+0

我在IRB下面定義了'method_missing',在IRB之外不會發生錯誤,從而得到各種錯誤。例如:'irb> def method_missing(* a); p a;結束; =>無; [:to_hash]; [:to_str]; C:/Ruby/lib/ruby/site_ruby/1.9.1/readline.rb:45:in raise:無法將TypeError轉換爲String(TypeError#to_str給出Array)(TypeError)' – Phrogz 2012-02-28 23:37:22

+1

隨機猜測(不是答案) :irb依靠和現有的monkeypatch到'method_missing',並重新定義它吹起來的東西。 [This](http://bugs.ruby-lang.org/issues/5077)看起來含糊不清。 – Phrogz 2012-02-28 23:38:39

+0

@Progrog這個bug報告有點有趣。但我認爲這不適用於這種情況。 – Kelvin 2012-02-28 23:49:52

回答

8

看起來它定義爲一個單方法的工作原理:

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

將其定義爲頂級方法替換BasicObject#method_missing的,這可能影響到一些IRB內部像Phrogz說。