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

ruby-changes:37251

From: nobu <ko1@a...>
Date: Mon, 19 Jan 2015 22:08:47 +0900 (JST)
Subject: [ruby-changes:37251] nobu:r49332 (trunk): class.c: prepend for each classes

nobu	2015-01-19 22:08:28 +0900 (Mon, 19 Jan 2015)

  New Revision: 49332

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

  Log:
    class.c: prepend for each classes
    
    * class.c (include_modules_at): allow prepend each modules upto
      once for each classes.  [EXPERIMENTAL]

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/test/ruby/test_module.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 49331)
+++ ChangeLog	(revision 49332)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Jan 19 22:08:26 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* class.c (include_modules_at): allow prepend each modules upto
+	  once for each classes.  [EXPERIMENTAL]
+
 Sun Jan 18 18:32:20 2015  SHIBATA Hiroshi  <shibata.hiroshi@g...>
 
 	* math.c (math_atan2): revive documentation before r49220.
Index: class.c
===================================================================
--- class.c	(revision 49331)
+++ class.c	(revision 49332)
@@ -817,7 +817,7 @@ rb_include_class_new(VALUE module, VALUE https://github.com/ruby/ruby/blob/trunk/class.c#L817
     return (VALUE)klass;
 }
 
-static int include_modules_at(const VALUE klass, VALUE c, VALUE module);
+static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
 
 void
 rb_include_module(VALUE klass, VALUE module)
@@ -832,7 +832,7 @@ rb_include_module(VALUE klass, VALUE mod https://github.com/ruby/ruby/blob/trunk/class.c#L832
 
     OBJ_INFECT(klass, module);
 
-    changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module);
+    changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
     if (changed < 0)
 	rb_raise(rb_eArgError, "cyclic include detected");
 }
@@ -845,7 +845,7 @@ add_refined_method_entry_i(st_data_t key https://github.com/ruby/ruby/blob/trunk/class.c#L845
 }
 
 static int
-include_modules_at(const VALUE klass, VALUE c, VALUE module)
+include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super)
 {
     VALUE p, iclass;
     int method_changed = 0, constant_changed = 0;
@@ -860,28 +860,27 @@ include_modules_at(const VALUE klass, VA https://github.com/ruby/ruby/blob/trunk/class.c#L860
 	    return -1;
 	/* ignore if the module included already in superclasses */
 	for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
-	    switch (BUILTIN_TYPE(p)) {
-	      case T_ICLASS:
+	    int type = BUILTIN_TYPE(p);
+	    if (type == T_ICLASS) {
 		if (RCLASS_M_TBL_WRAPPER(p) == RCLASS_M_TBL_WRAPPER(module)) {
 		    if (!superclass_seen) {
 			c = p;  /* move insertion point */
 		    }
 		    goto skip;
 		}
-		break;
-	      case T_CLASS:
+	    }
+	    else if (type == T_CLASS) {
+		if (!search_super) break;
 		superclass_seen = TRUE;
-		break;
 	    }
 	}
 	iclass = rb_include_class_new(module, RCLASS_SUPER(c));
 	c = RCLASS_SET_SUPER(c, iclass);
 
-	if (BUILTIN_TYPE(module) == T_ICLASS) {
-	    rb_module_add_to_subclasses_list(RBASIC(module)->klass, iclass);
-	}
-	else {
-	    rb_module_add_to_subclasses_list(module, iclass);
+	{
+	    VALUE m = module;
+	    if (BUILTIN_TYPE(m) == T_ICLASS) m = RBASIC(m)->klass;
+	    rb_module_add_to_subclasses_list(m, iclass);
 	}
 
 	if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
@@ -957,7 +956,7 @@ rb_prepend_module(VALUE klass, VALUE mod https://github.com/ruby/ruby/blob/trunk/class.c#L956
 	st_foreach(RCLASS_M_TBL(origin), move_refined_method,
 		   (st_data_t) RCLASS_M_TBL(klass));
     }
-    changed = include_modules_at(klass, klass, module);
+    changed = include_modules_at(klass, klass, module, FALSE);
     if (changed < 0)
 	rb_raise(rb_eArgError, "cyclic prepend detected");
     if (changed) {
Index: test/ruby/test_module.rb
===================================================================
--- test/ruby/test_module.rb	(revision 49331)
+++ test/ruby/test_module.rb	(revision 49332)
@@ -1725,6 +1725,17 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L1725
     assert_equal('hello!', foo.new.hello, bug9236)
   end
 
+  def test_multiple_prepend
+    m = labeled_module("M")
+    c1 = labeled_class("C1") {
+      prepend m
+    }
+    c2 = labeled_class("C2", c1) {
+      prepend m
+    }
+    assert_equal([m, c2, m, c1], c2.ancestors[0, 4])
+  end
+
   def test_class_variables
     m = Module.new
     m.class_variable_set(:@@foo, 1)

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

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