1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Use the flag for uninitialized module [Bug #18185]

Make `Module#ancestors` not to include `BasicObject`.
This commit is contained in:
Nobuyoshi Nakada 2021-09-24 01:30:00 +09:00
parent 65285bf673
commit b929af430c
Notes: git 2021-09-24 08:29:23 +09:00
2 changed files with 12 additions and 6 deletions

13
class.c
View file

@ -351,19 +351,22 @@ copy_tables(VALUE clone, VALUE orig)
static bool ensure_origin(VALUE klass);
/**
* If this flag is set, that module is allocated but not initialized yet.
*/
enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER5};
static inline bool
RMODULE_UNINITIALIZED(VALUE module)
{
return RCLASS_SUPER(module) == rb_cBasicObject;
return FL_TEST_RAW(module, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
}
void
rb_module_set_initialized(VALUE mod)
{
if (RMODULE_UNINITIALIZED(mod)) {
RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0);
FL_UNSET_RAW(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
/* no more re-initialization */
}
}
void
@ -817,7 +820,7 @@ rb_module_s_alloc(VALUE klass)
{
VALUE mod = class_alloc(T_MODULE, klass);
RCLASS_M_TBL_INIT(mod);
RB_OBJ_WRITE(mod, &RCLASS(mod)->super, rb_cBasicObject);
FL_SET(mod, RMODULE_ALLOCATED_BUT_NOT_INITIALIZED);
return mod;
}

View file

@ -449,7 +449,9 @@ class TestModule < Test::Unit::TestCase
class Bug18185 < Module
module InstanceMethods
end
attr_reader :ancestor_list
def initialize
@ancestor_list = ancestors
include InstanceMethods
end
class Foo
@ -470,6 +472,7 @@ class TestModule < Test::Unit::TestCase
assert_equal(1, anc.count(BasicObject), ->{anc.inspect})
b = c.new(key: 1)
assert_equal(1, b.key)
assert_not_include(mod.ancestor_list, BasicObject)
end
def test_dup