From: matz@... (Yukihiro Matsumoto) Date: 1999-08-10T00:26:37+09:00 Subject: [ruby-talk:00594] Re: Bug in Array#clone! In message "[ruby-talk:00590] Bug in Array#clone!" on 99/08/09, clemens.hintze@alcatel.de writes: |and here the next problem... :-) Well, thank .. you. |A short analyze of array.c let me believe, that `Array#clone' is wrong. |It seems only to clone the own (hidden) memory, but forget all about |possible instance variables. You are right. I modified CLONESETUP() to copy instance variables. |As I have seen, the datatype `RArray' has no `iv_table' pointer. But as |the example shows, instance variables could be stored too. But how? It is done by one big hash table of hashes. See variable.c around *_generic_ivar() functions. --- /tmp/ruby.h Tue Aug 10 00:21:16 1999 +++ ruby.h Mon Aug 9 23:52:35 1999 @@ -211,6 +211,7 @@ } -#define CLONESETUP(clone,obj) {\ +#define CLONESETUP(clone,obj) do {\ OBJSETUP(clone,rb_singleton_class_clone(RBASIC(obj)->klass),RBASIC(obj)->flags);\ rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\ -} + if (FL_TEST(obj, FL_EXIVAR)) rb_clone_generic_ivar(clone,obj);\ +} while (0) --- /tmp/variable.c Tue Aug 10 00:21:27 1999 +++ variable.c Tue Aug 10 00:03:34 1999 @@ -788,2 +788,3 @@ + if (!generic_iv_tbl) return; if (st_lookup(generic_iv_tbl, obj, &tbl)) { @@ -807,4 +808,4 @@ { - if (special_generic_ivar == 0) return; if (!generic_iv_tbl) return; + if (special_generic_ivar == 0) return; st_foreach(generic_iv_tbl, givar_i, 0); @@ -820,2 +821,14 @@ st_free_table(tbl); +} + +void +rb_clone_generic_ivar(clone, obj) + VALUE clone, obj; +{ + st_table *tbl; + + if (!generic_iv_tbl) return; + if (st_lookup(generic_iv_tbl, obj, &tbl)) { + st_add_direct(generic_iv_tbl, clone, st_copy(tbl)); + } }