Bug #2494
closedBug in th->method_missing_reason produces strange behavior with coercion
Description
=begin
Currently, Ruby uses check_funcall as part of its coercion behavior. That function calls check_funcall_exec, which calls method_missing without first setting th->method_missing_reason. As a result, the internal method_missing raises a NameError or NoMethodError based upon the LAST call to method_missing. If the last call was a vcall, the internal method_missing raises a NameError, which is not rescued by check_funcall.
You can see this bug in the following code:
class Blah
def setup_vcall
# Force th->method_missing_reason to be set to a vcall
not_there rescue nil
end
def method_missing(meth, *args)
puts "trying #{meth}"
super
end
end
b = Blah.new
b.setup_vcall
p [b].flatten
The patch is at http://gist.github.com/raw/259216/0a5749ab27a4bf7510cccb5cd52b793a82dcef1a/gistfile2.diff. This patch sets th->method_missing_reason, which will cause the internal call to method_missing to always raise a NoMethodError, which will be correctly rescued by check_funcall.
This bug caused problems in ActiveSupport (http://github.com/rails/rails/blob/master/activesupport/lib/active_support/whiny_nil.rb#L47-48), which we resolved by explicitly looking for :to_ary and raising NoMethodError. This should not have been needed, because calling super in method_missing would have raised NoMethodError if th->method_missing_reason was set correctly.
=end
Updated by naruse (Yui NARUSE) over 14 years ago
- Status changed from Open to Assigned
- Assignee set to nobu (Nobuyoshi Nakada)
=begin
=end
Updated by nobu (Nobuyoshi Nakada) over 14 years ago
- Category set to core
- Status changed from Assigned to Closed
=begin
Fixed in r26124.
=end