When I try define(by loading script&just typing in the pry) method_missing in pry it just exit to console(cmd on windows xp).
When I try typing it on the IRB, it goes into infinite loop or when I try loading the script(irb m.rb) it shows something like this:
D:\programowanie\Ruby>irb m.rb
m.rb(main):001:0> def method_missing name, *args, &block
m.rb(main):002:1> puts 'method is missing'
m.rb(main):003:1> end
=> nil
m.rb(main):004:0>
m.rb(main):005:0* some_missing_method("lol")method is missing
m.rb(main):005:0*
method is missing
method is missing
method is missing
m.rb(main):005:0>
method is missing
method is missing
method is missing
method is missing
and it exits to the console(cmd)
Here is my code:
def method_missing name, *args, &block
puts 'method is missing'
nil
end
some_missing_method("lol")
When I return something else it doesn't go into infinite loop but shows error instead(only first few lines are changing):
Number:
method is missing
method is missing
C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/readline.rb:45:in `raise': can't convert TypeError to String (TypeError#to_str gives Fixnum) (Typ
eError)
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/readline.rb:45:in `rescue in readline'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/readline.rb:39:in `readline'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/input-method.rb:115:in `gets'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:139:in `block (2 levels) in eval_input'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:273:in `signal_status'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:138:in `block in eval_input'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:188:in `call'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:188:in `buf_input'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:103:in `getc'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/slex.rb:205:in `match_io'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in each_top_level_statement'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:70:in `block in start'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:69:in `catch'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/irb.rb:69:in `start'
from C:/RailsInstaller/Ruby1.9.3/bin/irb:12:in `<main>'
String:
method is missing
method is missing
C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/readline.rb:45:in `rescue in readline': this_is_string (RuntimeError)
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/readline.rb:39:in `readline'
(..)
So this requires some understanding of Ruby's class/object/module hierarchy, as well as some understanding of how tools like IRB and Pry work. Take a look at this, which may blow your mind as it did mine - https://web.archive.org/web/20160319051340/http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html.
As for IRB and Pry, I don't know much about their code, but I know they basically work by reading your input and eval'ing + lots of magic.
As you seem to already know, when you're in irb/pry, you're inside the
Object
scope, from which nearly everything else inherits, including IRB and Pry themselves. So overriding something inObject
, likemethod_missing
, might change the behavior of everything that descends from it (i.e. Everything) including IRB/Pry. Pry is probably overridingmethod_missing
itself to do something very important, and your change is breaking that.You might try this as an interesting experiment:
That might give you some idea why it's happening, but the short answer is don't do it. Encapsulate your code into its own Module so that it doesn't interfere with anything else.
And I might be confusing myself here, but this might get things working again. It should restore whatever expectations Pry has about
Object#method_missing
:Edit
True, I don't think
BasicObject#method_missing
exists. But that's okay, because the abovesuper
will raise an error like "NoMethodError: undefined method missing_method' for #". That more or less restores the behavior that pry/irb seem to be expecting: thatObject#method_missing
should ultimately raise aNoMethodError
. That should fix the infinite recursive loop.However, a better solution (aside from not overwriting
Object#method_missing
in the first place) might be to raise aNoMethodError
yourself after doing whatever else you have to do:My guess is that pry is rescuing from a
NoMethodError
in some loop. So if it's never raised, the loop continues forever. If that's right, then the above should fix it. Not that I recommend it.