Consider modified modules initialized [Bug #18185]
This commit is contained in:
parent
854fe9d1c1
commit
65285bf673
Notes:
git
2021-09-24 08:29:24 +09:00
14
class.c
14
class.c
@ -357,6 +357,15 @@ RMODULE_UNINITIALIZED(VALUE module)
|
|||||||
return RCLASS_SUPER(module) == rb_cBasicObject;
|
return RCLASS_SUPER(module) == rb_cBasicObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_module_set_initialized(VALUE mod)
|
||||||
|
{
|
||||||
|
if (RMODULE_UNINITIALIZED(mod)) {
|
||||||
|
RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0);
|
||||||
|
/* no more re-initialization */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_module_check_initializable(VALUE mod)
|
rb_module_check_initializable(VALUE mod)
|
||||||
{
|
{
|
||||||
@ -916,10 +925,7 @@ ensure_includable(VALUE klass, VALUE module)
|
|||||||
{
|
{
|
||||||
rb_class_modify_check(klass);
|
rb_class_modify_check(klass);
|
||||||
Check_Type(module, T_MODULE);
|
Check_Type(module, T_MODULE);
|
||||||
if (RMODULE_UNINITIALIZED(module)) {
|
rb_module_set_initialized(module);
|
||||||
RB_OBJ_WRITE(module, &RCLASS(module)->super, 0);
|
|
||||||
/* no more re-initialization */
|
|
||||||
}
|
|
||||||
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
|
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
|
||||||
rb_raise(rb_eArgError, "refinement module is not allowed");
|
rb_raise(rb_eArgError, "refinement module is not allowed");
|
||||||
}
|
}
|
||||||
|
3
eval.c
3
eval.c
@ -424,6 +424,9 @@ rb_class_modify_check(VALUE klass)
|
|||||||
if (SPECIAL_CONST_P(klass)) {
|
if (SPECIAL_CONST_P(klass)) {
|
||||||
Check_Type(klass, T_CLASS);
|
Check_Type(klass, T_CLASS);
|
||||||
}
|
}
|
||||||
|
if (RB_TYPE_P(klass, T_MODULE)) {
|
||||||
|
rb_module_set_initialized(klass);
|
||||||
|
}
|
||||||
if (OBJ_FROZEN(klass)) {
|
if (OBJ_FROZEN(klass)) {
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ int rb_singleton_class_internal_p(VALUE sklass);
|
|||||||
VALUE rb_class_boot(VALUE);
|
VALUE rb_class_boot(VALUE);
|
||||||
VALUE rb_class_s_alloc(VALUE klass);
|
VALUE rb_class_s_alloc(VALUE klass);
|
||||||
VALUE rb_module_s_alloc(VALUE klass);
|
VALUE rb_module_s_alloc(VALUE klass);
|
||||||
|
void rb_module_set_initialized(VALUE module);
|
||||||
void rb_module_check_initializable(VALUE module);
|
void rb_module_check_initializable(VALUE module);
|
||||||
VALUE rb_make_metaclass(VALUE, VALUE);
|
VALUE rb_make_metaclass(VALUE, VALUE);
|
||||||
VALUE rb_include_class_new(VALUE, VALUE);
|
VALUE rb_include_class_new(VALUE, VALUE);
|
||||||
|
@ -446,6 +446,32 @@ class TestModule < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Bug18185 < Module
|
||||||
|
module InstanceMethods
|
||||||
|
end
|
||||||
|
def initialize
|
||||||
|
include InstanceMethods
|
||||||
|
end
|
||||||
|
class Foo
|
||||||
|
attr_reader :key
|
||||||
|
def initialize(key:)
|
||||||
|
@key = key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_module_subclass_initialize
|
||||||
|
mod = Bug18185.new
|
||||||
|
c = Class.new(Bug18185::Foo) do
|
||||||
|
include mod
|
||||||
|
end
|
||||||
|
anc = c.ancestors
|
||||||
|
assert_include(anc, mod)
|
||||||
|
assert_equal(1, anc.count(BasicObject), ->{anc.inspect})
|
||||||
|
b = c.new(key: 1)
|
||||||
|
assert_equal(1, b.key)
|
||||||
|
end
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
OtherSetup.call
|
OtherSetup.call
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user