mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
class.c: prepend for each classes
* class.c (include_modules_at): allow prepend each modules upto once for each classes. [EXPERIMENTAL] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49332 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4c3d694fb4
commit
59270c607b
3 changed files with 29 additions and 14 deletions
|
@ -1,3 +1,8 @@
|
|||
Mon Jan 19 22:08:26 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* math.c (math_atan2): revive documentation before r49220.
|
||||
|
|
27
class.c
27
class.c
|
@ -817,7 +817,7 @@ rb_include_class_new(VALUE module, VALUE super)
|
|||
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 module)
|
|||
|
||||
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, st_data_t value, st_data_t data)
|
|||
}
|
||||
|
||||
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, VALUE c, VALUE module)
|
|||
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 module)
|
|||
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) {
|
||||
|
|
|
@ -1725,6 +1725,17 @@ class TestModule < Test::Unit::TestCase
|
|||
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)
|
||||
|
|
Loading…
Add table
Reference in a new issue