From: myron.marston@... Date: 2014-09-12T06:47:21+00:00 Subject: [ruby-core:64990] [ruby-trunk - Bug #8982] NoMethodError#message produces surprising output when #inspect is defined on an anonymous class 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 "#" 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 -- https://bugs.ruby-lang.org/