Bug #8982
Updated by nobu (Nobuyoshi Nakada) about 11 years ago
=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>)) https://github.com/ruby/ruby/blob/870dc20922d1ab0b628d24e64e971e8eb77ecd61/error.c#L1091-1104 So it looks intentional, but I think this is a bug. =end