Bug #12344
closedcheck_funcall_respond_to behavior seems incorrect
Description
Prior to ruby 2.3, and specifically I believe prior to the implementation of this change:
Thu Aug 20 14:13:27 2015 Nobuyoshi Nakada nobu@ruby-lang.org
vm_eval.c (check_funcall_respond_to)
share the behavior with rb_obj_respond_to. [ruby-core:70460] [Bug #11465]vm_method.c (vm_respond_to)
extract from rb_obj_respond_to and merge r39881.
When a global method_missing was defined, I believe that "check_funcall_respond_to
" would not yield that the to_hash
method would be defined for objects of type String
. In Ruby 2.3, it behaves as if to_hash
is defined on a String
just due to the fact that we've added a global method_missing
. This is hugely problematic when calling a gsub as the second parameter is checked (in str_gsub
- string.c:4593) to see if it will act like a hash - i.e. is it a Hash
or does it have a to_hash
method. It appears that eventually vm_respond_to()
calls METHOD_ENTRY_BASIC()
which then makes the false statement that the object responds to the to_hash
method.
I believe that a possible fix is to have vm_eval.c - check_funcall_respond_to
be changed from:
static int
check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
{
return vm_respond_to(th, klass, recv, mid, TRUE);
}
to:
static int
check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid)
{
return rb_obj_respond_to(recv, mid, TRUE);
}
With the current behavior, the following in my opinion is incorrectly throwing the NameError
in the method_missing
.
def method_missing(name, *args, &block)
raise NameError, "#{name} not defined on #{self.inspect}"
end
puts "foo".gsub(/o/, "bar")
Updated by mbedalov (Matt Bedalov) almost 8 years ago
- Description updated (diff)
Updated by nobu (Nobuyoshi Nakada) almost 8 years ago
- Description updated (diff)
- Status changed from Open to Rejected
It's a common mistake, to define method_missing
but not respond_to_missing?
.