* vm_method.c (basic_obj_respond_to): new function to fundamental
behavior for #respond_to? * vm_method.c (basic_obj_respond_to): calls #respond_to_missing method if overridden, to check responsiveness of methods implemented by #method_missing. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25054 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bda0b012a8
commit
945f4df6a8
@ -23,6 +23,15 @@ Wed Sep 23 05:03:36 2009 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
|||||||
Module#define_method, even when that singleton class was of the right
|
Module#define_method, even when that singleton class was of the right
|
||||||
kind_of. A patch by Shane O'Brien [ruby-core:25632]
|
kind_of. A patch by Shane O'Brien [ruby-core:25632]
|
||||||
|
|
||||||
|
Tue Sep 22 22:56:48 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm_method.c (basic_obj_respond_to): new function to fundamental
|
||||||
|
behavior for #respond_to?
|
||||||
|
|
||||||
|
* vm_method.c (basic_obj_respond_to): calls #respond_to_missing
|
||||||
|
method if overridden, to check responsiveness of methods
|
||||||
|
implemented by #method_missing.
|
||||||
|
|
||||||
Tue Sep 22 16:34:33 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue Sep 22 16:34:33 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* st.c (st_table_entry, st_get_key): use st_index_t.
|
* st.c (st_table_entry, st_get_key): use st_index_t.
|
||||||
|
37
vm_method.c
37
vm_method.c
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me);
|
static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me);
|
||||||
|
|
||||||
static ID object_id;
|
static ID object_id, respond_to_missing;
|
||||||
static ID removed, singleton_removed, undefined, singleton_undefined;
|
static ID removed, singleton_removed, undefined, singleton_undefined;
|
||||||
static ID added, singleton_added, attached;
|
static ID added, singleton_added, attached;
|
||||||
|
|
||||||
@ -1114,21 +1114,30 @@ rb_method_basic_definition_p(VALUE klass, ID id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
basic_obj_respond_to(VALUE obj, ID id, int pub)
|
||||||
|
{
|
||||||
|
VALUE klass = CLASS_OF(obj);
|
||||||
|
|
||||||
|
if (!rb_method_boundp(klass, id, pub)) {
|
||||||
|
if (!rb_method_basic_definition_p(klass, respond_to_missing)) {
|
||||||
|
return RTEST(rb_funcall(obj, respond_to_missing, pub ? 1 : 2, ID2SYM(id), Qtrue));
|
||||||
|
}
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_obj_respond_to(VALUE obj, ID id, int priv)
|
rb_obj_respond_to(VALUE obj, ID id, int priv)
|
||||||
{
|
{
|
||||||
VALUE klass = CLASS_OF(obj);
|
VALUE klass = CLASS_OF(obj);
|
||||||
|
|
||||||
if (rb_method_basic_definition_p(klass, idRespond_to)) {
|
if (rb_method_basic_definition_p(klass, idRespond_to)) {
|
||||||
return rb_method_boundp(klass, id, !priv);
|
return basic_obj_respond_to(obj, id, !RTEST(priv));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE args[2];
|
return RTEST(rb_funcall(obj, idRespond_to, priv ? 2 : 1, ID2SYM(id), Qtrue));
|
||||||
int n = 0;
|
|
||||||
args[n++] = ID2SYM(id);
|
|
||||||
if (priv)
|
|
||||||
args[n++] = Qtrue;
|
|
||||||
return RTEST(rb_funcall2(obj, idRespond_to, n, args));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,6 +1147,7 @@ rb_respond_to(VALUE obj, ID id)
|
|||||||
return rb_obj_respond_to(obj, id, FALSE);
|
return rb_obj_respond_to(obj, id, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* obj.respond_to?(symbol, include_private=false) => true or false
|
* obj.respond_to?(symbol, include_private=false) => true or false
|
||||||
@ -1159,9 +1169,14 @@ obj_respond_to(int argc, VALUE *argv, VALUE obj)
|
|||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &mid, &priv);
|
rb_scan_args(argc, argv, "11", &mid, &priv);
|
||||||
id = rb_to_id(mid);
|
id = rb_to_id(mid);
|
||||||
if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
|
if (basic_obj_respond_to(obj, id, !RTEST(priv)))
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
obj_respond_to_missing(int argc, VALUE *argv, VALUE obj)
|
||||||
|
{
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1172,6 +1187,7 @@ Init_eval_method(void)
|
|||||||
#define rb_intern(str) rb_intern_const(str)
|
#define rb_intern(str) rb_intern_const(str)
|
||||||
|
|
||||||
rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
|
rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
|
||||||
|
rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, -1);
|
||||||
|
|
||||||
rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
|
rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
|
||||||
rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
|
rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
|
||||||
@ -1199,5 +1215,6 @@ Init_eval_method(void)
|
|||||||
undefined = rb_intern("method_undefined");
|
undefined = rb_intern("method_undefined");
|
||||||
singleton_undefined = rb_intern("singleton_method_undefined");
|
singleton_undefined = rb_intern("singleton_method_undefined");
|
||||||
attached = rb_intern("__attached__");
|
attached = rb_intern("__attached__");
|
||||||
|
respond_to_missing = rb_intern("respond_to_missing?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user