3

Scenario:

-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$ 

I ran with -f to avoid loading any irbrc stuff. I'm expecting to get nil when I input a. What's going on, and is there a workaround? I tried wrapping a with a begin/rescue Exception block but that didn't do anything.

This also happens with 1.9.2, but not 1.9.1.

More strange behavior:

-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$ 

This tells me that there's a bug in irb, or that some obscure bug in ruby is being triggered by irb. Also, after defining method_missing, even methods that exist like local_variables or eval cause the error.

Kelvin
  • 20,119
  • 3
  • 60
  • 68
  • I get a variety of errors under IRB with defining `method_missing`, errors that don't occur outside IRB. For example: `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)` – Phrogz Feb 28 '12 at 23:37
  • 1
    Random guess (not an answer): irb leans on and existing monkeypatch to `method_missing`, and redefining it blows things up. [This](http://bugs.ruby-lang.org/issues/5077) looks vaguely related. – Phrogz Feb 28 '12 at 23:38
  • @Phrogz That bug report was a bit entertaining. But I don't think it applies in this case. – Kelvin Feb 28 '12 at 23:49

1 Answers1

9

Looks like defining it as a singleton method works:

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

Defining it as a top-level method replaces BasicObject#method_missing, which probably affected some irb internals like Phrogz said.

Kelvin
  • 20,119
  • 3
  • 60
  • 68