From: nobu.nakada@... Date: 2004-01-16T11:56:08+09:00 Subject: [ruby-dev:22593] Re: marshaling a class which is defined under singleton class なかだです。 At Fri, 16 Jan 2004 02:19:30 +0900, Tanaka Akira wrote: > > 次のように、特異クラス内で定義したクラスを marshal するとエラーが出ま > す。それはいいのですが、load 時なのは変で dump 時なんじゃないでしょう > か。 > > % ruby -e ' > class << Object.new > class C > end > Marshal.load(Marshal.dump(C)) > end > ' > -e:5:in `load': undefined class/module Object::C (ArgumentError) > from -e:5 というより、これは別物になっています。 class C def c "C in toplevel" end end class << Object.new class C def c "C in singleton" end end c = C.new p c.c p Marshal.load(Marshal.dump(c)).c end クラス名からちゃんと復元できるか確認すべきかも。 Index: marshal.c =================================================================== RCS file: /cvs/ruby/src/ruby/marshal.c,v retrieving revision 1.110 diff -u -2 -p -d -r1.110 marshal.c --- marshal.c 27 Dec 2003 16:07:43 -0000 1.110 +++ marshal.c 16 Jan 2004 02:54:26 -0000 @@ -99,4 +99,17 @@ struct dump_call_arg { }; +static VALUE +class2name(klass) + VALUE klass; +{ + VALUE path = rb_class_path(klass); + char *n = RSTRING(path)->ptr; + + if (rb_path2class(n) != klass) { + rb_raise(rb_eArgError, "%s cannot be referfed", n); + } + return path; +} + static void w_long _((long, struct dump_arg*)); @@ -383,5 +396,5 @@ w_class(type, obj, arg, check) w_extended(klass, arg, check); w_byte(type, arg); - path = rb_class2name(klass); + path = RSTRING(class2name(klass))->ptr; w_unique(path, arg); } @@ -398,5 +411,5 @@ w_uclass(obj, base_klass, arg) if (klass != base_klass) { w_byte(TYPE_UCLASS, arg); - w_unique(rb_class2name(klass), arg); + w_unique(RSTRING(class2name(klass))->ptr, arg); } } @@ -518,5 +531,5 @@ w_object(obj, arg, limit) w_byte(TYPE_CLASS, arg); { - VALUE path = rb_class_path(obj); + VALUE path = class2name(obj); if (RSTRING(path)->ptr[0] == '#') { rb_raise(rb_eTypeError, "can't dump anonymous class %s", @@ -530,5 +543,5 @@ w_object(obj, arg, limit) w_byte(TYPE_MODULE, arg); { - VALUE path = rb_class_path(obj); + VALUE path = class2name(obj); if (RSTRING(path)->ptr[0] == '#') { rb_raise(rb_eTypeError, "can't dump anonymous module %s", -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦