From: Yukihiro Matsumoto Date: 2009-11-09T18:01:07+09:00 Subject: [ruby-core:26648] Re: [Bug #2346] Array(nil) fails after redefining NilClass.method_missing to throw NoMethodError Hi, In message "Re: [ruby-core:26628] [Bug #2346] Array(nil) fails after redefining NilClass.method_missing to throw NoMethodError" on Mon, 9 Nov 2009 01:56:47 +0900, Romulo Ceccon writes: |Given the following script: | | print "Array(nil) => ", Array(nil).inspect, "\n" | print "Array.try_convert(nil) => ", Array.try_convert(nil).inspect, "\n" | class NilClass | private | def method_missing(method, *args, &block) | raise NoMethodError | end | end | print "Array(nil) => ", Array(nil).inspect, "\n" | print "Array.try_convert(nil) => ", Array.try_convert(nil).inspect, "\n" | |Ruby 1.9.2dev returns this: | | $ ruby -v | ruby 1.9.2dev (2009-11-08 trunk 25690) [i386-mswin32_90] | | $ ruby nil_ary.rb | Array(nil) => [] | Array.try_convert(nil) => nil | nil_ary.rb:6:in `method_missing': NoMethodError (NoMethodError) | from nil_ary.rb:9:in `Array' | from nil_ary.rb:9:in `
' Because 1.9 actually calls the conversion method, where 1.8 checks method existence by respond_to? In other words, 1.9 respects duck typing more thoroughly. This one is a side effect. If you don't want see exception raised, use super from method_missing, or you can do like the following (not recommended): print "Array(nil) => ", Array(nil).inspect, "\n" print "Array.try_convert(nil) => ", Array.try_convert(nil).inspect, "\n" class NilClass private def method_missing(method, *args, &block) raise NoMethodError.new("undefined method #{method}", method), caller(1) end end print "Array(nil) => ", Array(nil).inspect, "\n" print "Array.try_convert(nil) => ", Array.try_convert(nil).inspect, "\n" matz.