Issue #8982 has been updated by jeremyevans0 (Jeremy Evans).

Backport deleted (1.9.3: UNKNOWN, 2.0.0: UNKNOWN)
Status changed from Open to Feedback

Starting in Ruby 2.3, you can do this:

```ruby
begin
instance = klass.new
puts "#inspect output: #{instance.inspect} (#{instance.inspect.length} chars)"
instance.undefined_method
rescue NoMethodError => e
puts "undefined method `#{e.name}' for #{e.receiver.inspect}"
end
```

Hopefully that provides a way to accomplish what you want. Do you think this is sufficient for your needs?

----------------------------------------
Bug #8982: NoMethodError#message produces surprising output when #inspect is defined on an anonymous class
https://bugs.ruby-lang.org/issues/8982#change-80791

* Author: myronmarston (Myron Marston)
* Status: Feedback
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
* Backport: 
----------------------------------------
=begin
Given the following script:

 def raise_no_method_error_for_anonymous_class_with_inspect(&block)
   klass = Class.new do
     define_method(:inspect, &block)
   end

   begin
     instance = klass.new
     puts "#inspect output: #{instance.inspect} (#{instance.inspect.length} chars)"
     instance.undefined_method
   rescue NoMethodError => e
     puts e.message
   end

   puts
 end

 raise_no_method_error_for_anonymous_class_with_inspect do
   "#<MyAnonymousClass>"
 end

 raise_no_method_error_for_anonymous_class_with_inspect do
   "<MyAnonymousClass>"
 end

 raise_no_method_error_for_anonymous_class_with_inspect do
   "#<MyAnonymousClass #{'a' * 45}>"
 end

 raise_no_method_error_for_anonymous_class_with_inspect do
   "#<MyAnonymousClass #{'a' * 46}>"
 end

It produces the following output:

 #inspect output: #<MyAnonymousClass> (19 chars)
 undefined method `undefined_method' for #<MyAnonymousClass>

 #inspect output: <MyAnonymousClass> (18 chars)
 undefined method `undefined_method' for <MyAnonymousClass>:#<Class:0x1017270e8>

 #inspect output: #<MyAnonymousClass aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> (65 chars)
 undefined method `undefined_method' for #<MyAnonymousClass aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>

 #inspect output: #<MyAnonymousClass aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> (66 chars)
 undefined method `undefined_method' for #<#<Class:0x1017266e8>:0x101726698>

There are two surprising things here:

* It matters whether or not the first character in my `inspect` is a `#`.  If it's not, ruby appends the class's `#inspect` output to it.
* It matters how long my `inspect` string is.  If it's less than 66 characters, it's used; if it's more than 65, it's discarded, and the default anonymous `#inspect` is used instead.

Both of these things are extremely surprising and seem very arbitrary and inconsistent.

I brought this up on ruby parley and @charliesome was kind enough to point me to the code that's the source of this issue:

((<error.c#L1091-1104|URL:https://github.com/ruby/ruby/blob/870dc20922d1ab0b628d24e64e971e8eb77ecd61/error.c#L1091-1104>))

So it looks intentional, but I think this is a bug.
=end




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