Issue #8982 has been updated by Myron Marston.


So I've run into this issue again, and as it turns out, this is a much more widespread problem than I first thought.  I originally thought that this was just a problem with anonymous classes, but that's not the case; now I'm running up against it in RSpec. We're trying to define `RSpec::Core::ExampleGroup#inspect` so that when users have a typo (or otherwise trigger a `NoMethodError` for a message sent to an example group) the example group is represented in the error message in a pretty, useful way, rather than having the obscure hex value:

https://github.com/rspec/rspec-core/issues/1590
https://github.com/rspec/rspec-core/pull/1687

As far as I can tell, it's impossible to achieve this behavior on MRI, and that really bums me out :(.

Any chance this can get fixed in Ruby 2.2?

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

* Author: Myron Marston
* Status: Open
* Priority: Normal
* Assignee: 
* Category: 
* Target version: 
* ruby -v: ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
* Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN
----------------------------------------
=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/