Project

General

Profile

Actions

Bug #2346

closed

Array(nil) fails after redefining NilClass.method_missing to throw NoMethodError

Added by romuloceccon (Rômulo Ceccon) over 15 years ago. Updated about 14 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.2dev (2009-11-08 trunk 25690) [i386-mswin32_90]
Backport:
[ruby-core:26628]

Description

=begin
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 `'

while for Ruby 1.8.8dev it is ok:

$ ruby -v
ruby 1.8.8dev (2009-10-31 revision 25583) [i386-mswin32_90]

$ ruby nil_ary.rb
Array(nil) => []
Array.try_convert(nil) => nil
Array(nil) => []
Array.try_convert(nil) => nil

Ruby 1.9.1-p0 (Windows) also runs fine. I don't understand what is happening here, but the behavior change breaks Rails 2.3.4 because active_support/whiny_nil.rb redefines NilClass.method_missing with code equivalent to the above one.
=end

Actions #1

Updated by matz (Yukihiro Matsumoto) over 15 years ago

=begin
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.

=end

Actions #2

Updated by matz (Yukihiro Matsumoto) over 15 years ago

  • Status changed from Open to Rejected

=begin

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0