From 5c7dfe85a1dc49334e2828791f0ade42eee662db Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sun, 31 Aug 2025 03:24:25 +0900 Subject: Initialize class dup/clone before calling initialize_dup/initialize_clone Previously, you could override the class initialize_dup/initialize_clone method and the class hierarchy would not be set correctly inside the method before calling super. This removes Module#initialize_copy, and instead makes Object#dup/clone call the underlying C function (rb_mod_init_copy) before calling the appropriate initialize_dup/initialize_clone method. This results in the following fixes: * The appropriate initialize_dup method is called (dup on a class will respect superclass initialize_dup). * Inside class initialize_dup/initialize_clone/initialize_copy, class ancestor hierarchy is correct. * Calling singleton_class inside initialize_dup no longer raises a TypeError later in dup. * Calling singleton_class.ancestors inside initialize_dup no longer results in missing ancestors. Fixes [Bug #21538] --- object.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index 6aa9c27f9d..56afc7e99b 100644 --- a/object.c +++ b/object.c @@ -409,7 +409,7 @@ init_copy(VALUE dest, VALUE obj) break; case T_CLASS: case T_MODULE: - // noop: handled in class.c: rb_mod_init_copy + rb_mod_init_copy(dest, obj); break; case T_OBJECT: rb_obj_copy_ivar(dest, obj); @@ -4571,7 +4571,6 @@ InitVM_Object(void) rb_define_method(rb_cModule, "<=", rb_class_inherited_p, 1); rb_define_method(rb_cModule, ">", rb_mod_gt, 1); rb_define_method(rb_cModule, ">=", rb_mod_ge, 1); - rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */ rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); rb_define_alias(rb_cModule, "inspect", "to_s"); rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */ -- cgit v1.2.3