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

ruby-changes:25477

From: shugo <ko1@a...>
Date: Wed, 7 Nov 2012 13:10:04 +0900 (JST)
Subject: [ruby-changes:25477] shugo:r37534 (trunk): * eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created

shugo	2012-11-07 13:09:51 +0900 (Wed, 07 Nov 2012)

  New Revision: 37534

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

  Log:
    * eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created
      refinement module, and don't override method_added.
    
    * vm_method.c (rb_method_entry_make): check redefinition of
      optimized methods when a method is added to a refinement module.
      [ruby-core:48970] [Bug #7290]
    
    * test/ruby/test_refinement.rb: related test.

  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/include/ruby/ruby.h
    trunk/test/ruby/test_refinement.rb
    trunk/vm_method.c

Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 37533)
+++ include/ruby/ruby.h	(revision 37534)
@@ -721,6 +721,7 @@
 #define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
 #define RMODULE_SUPER(m) RCLASS_SUPER(m)
 #define RMODULE_IS_OVERLAID FL_USER2
+#define RMODULE_IS_REFINEMENT FL_USER3
 
 struct RFloat {
     struct RBasic basic;
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37533)
+++ ChangeLog	(revision 37534)
@@ -1,3 +1,14 @@
+Wed Nov  7 12:49:39 2012  Shugo Maeda  <shugo@r...>
+
+	* eval.c (rb_mod_refine): set RMODULE_IS_REFINEMENT to a created
+	  refinement module, and don't override method_added.
+	
+	* vm_method.c (rb_method_entry_make): check redefinition of
+	  optimized methods when a method is added to a refinement module.
+	  [ruby-core:48970] [Bug #7290]
+
+	* test/ruby/test_refinement.rb: related test.
+
 Wed Nov  7 11:48:14 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* misc/ruby-additional.el (ruby-mode-set-encoding): now encoding needs
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 37533)
+++ vm_method.c	(revision 37534)
@@ -167,6 +167,8 @@
 
 static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
 
+void rb_redefine_opt_method(VALUE, ID);
+
 static rb_method_entry_t *
 rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type,
 		     rb_method_definition_t *def, rb_method_flag_t noex)
@@ -196,6 +198,14 @@
 #if NOEX_NOREDEF
     rklass = klass;
 #endif
+    if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
+	ID id_refined_class;
+	VALUE refined_class;
+
+	CONST_ID(id_refined_class, "__refined_class__");
+	refined_class = rb_ivar_get(klass, id_refined_class);
+	rb_redefine_opt_method(refined_class, mid);
+    }
     klass = RCLASS_ORIGIN(klass);
     mtbl = RCLASS_M_TBL(klass);
 
Index: eval.c
===================================================================
--- eval.c	(revision 37533)
+++ eval.c	(revision 37534)
@@ -1157,22 +1157,7 @@
     return self;
 }
 
-void rb_redefine_opt_method(VALUE, ID);
-
 static VALUE
-refinement_module_method_added(VALUE mod, VALUE mid)
-{
-    ID id = SYM2ID(mid);
-    ID id_refined_class;
-    VALUE klass;
-
-    CONST_ID(id_refined_class, "__refined_class__");
-    klass = rb_ivar_get(mod, id_refined_class);
-    rb_redefine_opt_method(klass, id);
-    return Qnil;
-}
-
-static VALUE
 refinement_module_include(int argc, VALUE *argv, VALUE module)
 {
     rb_thread_t *th = GET_THREAD();
@@ -1234,12 +1219,11 @@
     mod = rb_hash_lookup(refinements, klass);
     if (NIL_P(mod)) {
 	mod = rb_module_new();
+	FL_SET(mod, RMODULE_IS_REFINEMENT);
 	CONST_ID(id_refined_class, "__refined_class__");
 	rb_ivar_set(mod, id_refined_class, klass);
 	CONST_ID(id_defined_at, "__defined_at__");
 	rb_ivar_set(mod, id_defined_at, module);
-	rb_define_singleton_method(mod, "method_added",
-				   refinement_module_method_added, 1);
 	rb_define_singleton_method(mod, "include",
 				   refinement_module_include, -1);
 	rb_using_refinement(cref, klass, mod);
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 37533)
+++ test/ruby/test_refinement.rb	(revision 37534)
@@ -191,6 +191,18 @@
     assert_equal(0, 1 / 2)
   end
 
+  def test_override_builtin_method_with_method_added
+    m = Module.new {
+      refine Fixnum do
+        def self.method_added(*args); end
+        def +(other) "overriden" end
+      end
+    }
+    assert_equal(3, 1 + 2)
+    assert_equal("overriden", m.module_eval { 1 + 2 })
+    assert_equal(3, 1 + 2)
+  end
+
   def test_return_value_of_refine
     mod = nil
     result = nil

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

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