Issue #5283 has been updated by Koichi Sasada.

Status changed from Open to Assigned
Assignee set to Nobuyoshi Nakada


----------------------------------------
Bug #5283:  ????鴻?????吾?с?????? clone ???≪?????莖??
https://bugs.ruby-lang.org/issues/5283

Author: satoshi shiba
Status: Assigned
Priority: Normal
Assignee: Nobuyoshi Nakada
Category: 
Target version: 
ruby -v: -


 ??????潟????障?????
 ????鴻?????吾?с?????? clone ????????????????????ゃ????莖???????????????????????
 
 # ??泣?潟?????潟?若??
 String.class_eval do
   def self.singleton_method_added(mid)
     puts("singleton_method_added: self = #{self}, mid = #{mid}")
   end
 end
 
 puts("start clone")
 StrClone = String.clone
 puts("finish clone")
 
 # ??泣?潟?????潟?若??????茵?腟????
 singleton_method_added: self = String, mid = singleton_method_added
 start clone
 singleton_method_added: self = String, mid = try_convert
 singleton_method_added: self = String, mid = singleton_method_added
 finish clone
 
 
 
 筝?荐????泣?潟?????潟?若?????絎?茵???????????String ????鴻?? clone ????????<?純???????????
 ??????? StrClone ???潟????若?????????????????String ????鴻?絲??????
 singleton_method_added ?????若?喝?冴????????絎?茵?腟??????????????阪??????????障?????
 莖???????с????????????鴻?????吾?с?????? clone ?????? clone ????????鴻?????吾??
 ??????? singleton_method_added ?????若?喝?冴?????????????罕?????с??????????????
 
 筝?荐????泣?潟?????潟?若?????翫?????StrClone ??? singleton_method_added ?????若?喝??
 ?????????????????????????? singleton_method_added ?????若?喝?冴???????????????????緇???????
 singleton_method_added ???篏睡?????????障????????
 
 筝?荐????泣?潟?????潟?若????? String ????鴻?? singleton_method_added ?????若?喝?冴??
 ????????????????rb_singleton_class_clone(class.c) ?????????障?????
 rb_singleton_class_clone ??с???篁ヤ????????????合?違???鴻??ゃ?潟?鴻?帥?潟?劫?????
 ?????潟????若????????с???????????????????"__attached__" ?????????ゃ?潟?鴻?帥?潟?劫????違??
 ??潟????若????????障?????
 
 
 
 VALUE
 rb_singleton_class_clone(VALUE obj)
 {
         ...
         if (RCLASS_IV_TBL(klass)) {
             /* ??ゃ?潟?鴻?帥?潟?劫????違??潟????? */
             RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
         }
         ...
         RCLASS_M_TBL(clone) = st_init_numtable();
         data.tbl = RCLASS_M_TBL(clone);
         data.klass = (VALUE)clone;
         /* ??<?純??????????若??????潟????若??method_added ???若?喝?冴?? */
         st_foreach(RCLASS_M_TBL(klass), clone_method,
                    (st_data_t)&data);
         ...
 }
 
 
 
 篁???????????翫????????????"__attached__" ????????鴻??潟????弱????с????? String
 ????鴻??????????????障?????singleton_method_added ?????若?喝?冴?? CALL_METHOD_HOOK
 ??с???篁ヤ????????????????激?若???????合?違???鴻?? "__attached__" ??????c?羆阪????
 ??????с????<?純??????????若????????潟????若????????????若?喝?冴??
 singleton_method_added ????激?若????????String ????c?????障?????
 
 
 
 #define CALL_METHOD_HOOK(klass, hook, mid) do {         \
         const VALUE arg = ID2SYM(mid);                  \
         VALUE recv_class = (klass);                     \
         ID hook_id = (hook);                            \
         if (FL_TEST((klass), FL_SINGLETON)) {           \
             recv_class = rb_ivar_get((klass), attached);\
             hook_id = singleton_##hook;                 \
         }                                               \
         rb_funcall2(recv_class, hook_id, 1, &arg);      \
     } while (0)
 
 
 
 ???????????????????篁?罕???????????障?c????????????????????????????????????с????????
 singleton_method_added ????激?若?????????若?喝???????鴻?????眼???????????????
 ???????????????篏?????????????с?????<?若???絨??綣??c????????障?????
 rb_obj_clone ??с??
 RBASIC(clone)->klass = rb_singleton_class_clone_and_attach(obj, clone);
 ????臀????????????????????????????????筝?絎???????с????????????????????????????????????医晃
 ?????с?????
 
 篁ヤ???????????????????蕁???????????????障?????
 
 
 # ?????????
 
 Index: object.c
 ===================================================================
 --- object.c    (revision 33202)
 +++ object.c    (working copy)
 @@ -268,6 +268,7 @@
   *  the class.
   */
 
 +VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
  VALUE
  rb_obj_clone(VALUE obj)
  {
 @@ -277,9 +278,9 @@
          rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
      }
      clone = rb_obj_alloc(rb_obj_class(obj));
 -    RBASIC(clone)->klass = rb_singleton_class_clone(obj);
      RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone,
 FL_TAINT) | FL_TEST(clone, FL_UNTRUSTED)) &
 ~(FL_FREEZE|FL_FINALIZE|FL_MARK);
      init_copy(clone, obj);
 +    RBASIC(clone)->klass = rb_singleton_class_clone_and_attach(obj, clone);
      rb_funcall(clone, id_init_clone, 1, obj);
      RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
 
 Index: class.c
 ===================================================================
 --- class.c     (revision 33202)
 +++ class.c     (working copy)
 @@ -219,9 +219,17 @@
      return rb_mod_init_copy(clone, orig);
  }
 
 +VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
 +
  VALUE
  rb_singleton_class_clone(VALUE obj)
  {
 +    return rb_singleton_class_clone_and_attach(obj, Qundef);
 +}
 +
 +VALUE
 +rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
 +{
      VALUE klass = RBASIC(obj)->klass;
 
      if (!FL_TEST(klass, FL_SINGLETON))
 @@ -246,6 +254,10 @@
             RCLASS_CONST_TBL(clone) = st_init_numtable();
             st_foreach(RCLASS_CONST_TBL(klass), clone_const_i,
 (st_data_t)RCLASS_CONST_TBL(clone));
         }
 +       if (attach != Qundef) {
 +           rb_singleton_class_attached(clone, attach);
 +       }
         RCLASS_M_TBL(clone) = st_init_numtable();
         data.tbl = RCLASS_M_TBL(clone);
         data.klass = (VALUE)clone;


-- 
http://bugs.ruby-lang.org/