[前][次][番号順一覧][スレッド一覧]

ruby-changes:13291

From: matz <ko1@a...>
Date: Wed, 23 Sep 2009 17:47:04 +0900 (JST)
Subject: [ruby-changes:13291] Ruby:r25054 (trunk): * vm_method.c (basic_obj_respond_to): new function to fundamental

matz	2009-09-23 17:46:44 +0900 (Wed, 23 Sep 2009)

  New Revision: 25054

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25054

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/vm_method.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25053)
+++ ChangeLog	(revision 25054)
@@ -23,6 +23,15 @@
 	  Module#define_method, even when that singleton class was of the right
 	  kind_of. A patch by Shane O'Brien [ruby-core:25632]
 
+Tue Sep 22 22:56:48 2009  Yukihiro Matsumoto  <matz@r...>
+
+	* 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@r...>
 
 	* st.c (st_table_entry, st_get_key): use st_index_t.
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 25053)
+++ vm_method.c	(revision 25054)
@@ -8,7 +8,7 @@
 
 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 added, singleton_added, attached;
 
@@ -1114,21 +1114,30 @@
     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
 rb_obj_respond_to(VALUE obj, ID id, int priv)
 {
     VALUE klass = CLASS_OF(obj);
 
     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 {
-	VALUE args[2];
-	int n = 0;
-	args[n++] = ID2SYM(id);
-	if (priv)
-	    args[n++] = Qtrue;
-	return RTEST(rb_funcall2(obj, idRespond_to, n, args));
+	return RTEST(rb_funcall(obj, idRespond_to, priv ? 2 : 1, ID2SYM(id), Qtrue));
     }
 }
 
@@ -1138,6 +1147,7 @@
     return rb_obj_respond_to(obj, id, FALSE);
 }
 
+
 /*
  *  call-seq:
  *     obj.respond_to?(symbol, include_private=false) => true or false
@@ -1159,12 +1169,17 @@
 
     rb_scan_args(argc, argv, "11", &mid, &priv);
     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 Qfalse;
 }
 
+static VALUE
+obj_respond_to_missing(int argc, VALUE *argv, VALUE obj)
+{
+    return Qfalse;
+}
+
 void
 Init_eval_method(void)
 {
@@ -1172,6 +1187,7 @@
 #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_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, "undef_method", rb_mod_undef_method, -1);
@@ -1199,5 +1215,6 @@
     undefined = rb_intern("method_undefined");
     singleton_undefined = rb_intern("singleton_method_undefined");
     attached = rb_intern("__attached__");
+    respond_to_missing = rb_intern("respond_to_missing?");
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]