[ruby-core:93509] [Ruby master Bug#11493] IRB/Ruby completely exits when attempting to use NoMethodError exception in BasicObject
From:
merch-redmine@...
Date:
2019-07-03 04:59:17 UTC
List:
ruby-core #93509
Issue #11493 has been updated by jeremyevans0 (Jeremy Evans).
This error still occurs in master. However, I'm not sure it is fixable with the example you gave. Your example does not raise `NoMethodError`, it raises `NameError`, because you used `NoMethodError` instead of `::NoMethodError`. Even if you fix that, defining `BasicObject#method_missing` overrides the existing version, which breaks ton of internal code, not just irb. Even a simple thing like using backticks is broken if you do that (and irb ends up using backticks), because Ruby will attempt to call such a `method_missing` method (in `rb_check_funcall_default`) in many cases.
If you do want to wrap `NoMethodError`s with a different exception message, you could try:
```ruby
module BasicObjectMM
def method_missing(name, *args, &block)
super
rescue => e
e.message.replace("'#{name}' is an undefined method, dude!")
::Kernel.raise(e)
end
end
BasicObject.prepend(BasicObjectMM)
```
----------------------------------------
Bug #11493: IRB/Ruby completely exits when attempting to use NoMethodError exception in BasicObject
https://bugs.ruby-lang.org/issues/11493#change-79072
* Author: iMIchael (Michael Martinez)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: 2.2.0
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
# Summary
Was playing around with BasicObject to implement my own undefined method message and found this issue in IRB
~~~
$ ruby --version
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
$ irb
2.2.0 :002 > class BasicObject
2.2.0 :003?> def method_missing(name, *args, &block)
2.2.0 :004?> raise(NoMethodError, " '#{name}' is an undefined method, dude!")
2.2.0 :005?> end
2.2.0 :006?> end
=> :method_missing
2.2.0 :008 > 234234.asdasdasd
NameError: uninitialized constant BasicObject::NoMethodError
(irb):4:in `method_missing': uninitialized constant BasicObject::NoMethodError (NameError)
from /Users/home/.rvm/scripts/irbrc.rb:32:in `initialize'
from /Users/home/.rvm/scripts/irbrc.rb:32:in `open'
from /Users/home/.rvm/scripts/irbrc.rb:32:in `block in <top (required)>'
(irb):4:in `method_missing': uninitialized constant BasicObject::NoMethodError (NameError)
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/workspace.rb:106:in `sub'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/workspace.rb:106:in `filter_backtrace'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:511:in `block (3 levels) in eval_input'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:510:in `each'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:510:in `block (2 levels) in eval_input'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:623:in `signal_status'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:486:in `block in eval_input'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:485:in `eval_input'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:395:in `block in start'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:394:in `catch'
from /Users/home/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/irb.rb:394:in `start'
from /Users/home/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>'
$ echo $?
1
~~~
# Expected Results
I expect IRB to handle Ruby errors without exiting completely. The same way "foo".asdfasdf() raises a NoMethodError, but doesn't actually completely die.
# Actual Results
Fatal error resulting in the Ruby process exiting.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>