From: "alexeymuranov (Alexey Muranov)" Date: 2013-10-18T13:57:40+09:00 Subject: [ruby-core:57929] [ruby-trunk - Bug #8982] NoMethodError#message produces surprising output when #inspect is defined on an anonymous class Issue #8982 has been updated by alexeymuranov (Alexey Muranov). nobu (Nobuyoshi Nakada) wrote: > '#' at the beginning is assumed the string is same as Object#inspect, otherwise its class name is appended since the string may not represent the class. > If the `inspect` string is too long, just ignore it and use default conersion method Looks like defensive programming to me. ---------------------------------------- Bug #8982: NoMethodError#message produces surprising output when #inspect is defined on an anonymous class https://bugs.ruby-lang.org/issues/8982#change-42513 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 =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 "#" end raise_no_method_error_for_anonymous_class_with_inspect do "" end raise_no_method_error_for_anonymous_class_with_inspect do "#" end raise_no_method_error_for_anonymous_class_with_inspect do "#" end It produces the following output: #inspect output: # (19 chars) undefined method `undefined_method' for # #inspect output: (18 chars) undefined method `undefined_method' for :# #inspect output: # (65 chars) undefined method `undefined_method' for # #inspect output: # (66 chars) undefined method `undefined_method' for #<#: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: (()) So it looks intentional, but I think this is a bug. =end -- http://bugs.ruby-lang.org/