3
シナリオ: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$
私はどんなirbrcものをロード避けるために、-fで走りました。 a
と入力したときにnilが得られると考えています。何が起こっていて、回避策がありますか?私はをbegin
/rescue Exception
ブロックでラップしようとしましたが、何もしませんでした。
これも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$
これはRubyでいくつかのあいまいなバグがIRBによってトリガされていることがIRBのバグだか、と言われます。また、method_missingを定義した後に、local_variables
またはeval
のようなメソッドであってもエラーが発生します。トップレベルのメソッドとして定義
def self.method_missing(sym, *args); @v[sym]; end
がPhrogzが言ったように、おそらくいくつかのIRBの内部に影響を与えたBasicObject番号のmethod_missingを、置き換えます。
IRBの下では発生しないエラーである 'method_missing'を定義して、IRBの下でさまざまなエラーが発生します。次に例を示します。 'irb> def method_missing(* a); p a;終わり; => nil; [:to_hash]; [:to_str]; C:/Ruby/lib/ruby/site_ruby/1.9.1/readline.rb:45:raise:TypeErrorをStringに変換できません(TypeError#to_strが配列を返します)(TypeError) ' – Phrogz
ランダム推測(答えではありません) :irbは 'method_missing'に既存のmonkeypatchを頼りにして、それを再定義することで物事が爆発します。 [This](http://bugs.ruby-lang.org/issues/5077)は曖昧に見えます。 – Phrogz
@Phrogzそのバグレポートはちょっと面白かったです。しかし、私はそれがこの場合に当てはまるとは思わない。 – Kelvin