[#45341] 非同期割り込みに対する対処案(日本語版) — SASADA Koichi <ko1@...>

 ささだです.

28 messages 2012/03/11
[#45816] Re: 非同期割り込みに対する対処案(日本語版) — SASADA Koichi <ko1@...> 2012/06/25

 ささだです.

[#45817] Re: 非同期割り込みに対する対処案(日本語版) — Tanaka Akira <akr@...> 2012/06/25

2012年6月25日 18:26 SASADA Koichi <[email protected]>:

[#45819] Re: 非同期割り込みに対する対処案(日本語版) — SASADA Koichi <ko1@...> 2012/06/25

 ささだです.

[#45820] Re: 非同期割り込みに対する対処案(日本語版) — Tanaka Akira <akr@...> 2012/06/25

2012年6月25日 19:39 SASADA Koichi <[email protected]>:

[#45827] Re: 非同期割り込みに対する対処案(日本語版) — SASADA Koichi <ko1@...> 2012/06/25

(2012/06/25 20:32), Tanaka Akira wrote:

[#45841] Re: 非同期割り込みに対する対処案(日本語版) — Tanaka Akira <akr@...> 2012/06/25

2012年6月26日 3:40 SASADA Koichi <[email protected]>:

[#45844] Re: 非同期割り込みに対する対処案(日本語版) — SASADA Koichi <ko1@...> 2012/06/25

(2012/06/26 5:07), Tanaka Akira wrote:

[#45372] Marshal.dumpにおけるインスタンス変数の取り扱いについて — keiju@... (Keiju ISHITSUKA)

けいじゅ@いしつかです.

14 messages 2012/03/16
[#45376] Re: Marshal.dumpにおけるインスタンス変数の取り扱いについて — Yukihiro Matsumoto <matz@...> 2012/03/17

まつもと ゆきひろです

[#45377] Re: Marshal.dumpにおけるインスタンス変数の取り扱いについて — keiju@... (石塚圭樹) 2012/03/17

けいじゅ@いしつかです.

[#45381] Re: Marshal.dumpにおけるインスタンス変数の取り扱いについて — Yukihiro Matsumoto <matz@...> 2012/03/17

まつもと ゆきひろです

[#45399] Re: Marshal.dumpにおけるインスタンス変数の取り扱いについて — keiju@... (石塚圭樹) 2012/03/18

けいじゅ@いしつかです.

[#45412] [ruby-trunk - Feature #6177][Open] array.cのrb_ary_equal()の高速化 — "Glass_saga (Masaki Matsushita)" <glass.saga@...>

13 messages 2012/03/20

[#45471] [ruby-trunk - Bug #6230][Open] [WEBrick] WEBrick::HTTPResponse#body の IO オブジェクトの読み込みに read メソッドを使っているため必要以上にブロックされる — "nobuoka (yu nobuoka)" <nobuoka@...>

7 messages 2012/03/30

[ruby-dev:45325] [ruby-trunk - Bug #5283][Assigned] クラスオブジェクトの clone に関する質問

From: Koichi Sasada <redmine@...>
Date: 2012-03-11 06:30:05 UTC
List: ruby-dev #45325
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__" によって決定す
 るので、メソッドテーブルをコピーするときに呼び出す
 singleton_method_added のレシーバが、String になっています。
 
 
 
 #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)
 
 
 
 このようになるのが仕様として定まっているのかどうかが分からないのですが、
 singleton_method_added のレシーバをクローン先のクラスに変更するようにし
 たパッチを作成したので、本メールの末尾に張っておきます。
 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/

In This Thread

Prev Next