Issue #8982 has been reported by myronmarston (Myron Marston).

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

Author: myronmarston (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


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:

https://github.com/ruby/ruby/blob/870dc20922d1ab0b628d24e64e971e8eb77ecd61/error.c#L1091-1104

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



-- 
http://bugs.ruby-lang.org/