From: keiju@... (=?ISO-2022-JP?B?GyRCQFBETTc9PHkbKEI=?= ) Date: 1998-03-07T20:06:41+09:00 Subject: [ruby-dev:1605] Re: [BUG] String.dup けいじゅ@日本ラショナルソフトウェアです. In [ruby-dev :01593 ] the message: "[ruby-dev:1593] Re: [BUG] String.dup ", on Mar/05 12:18(JST) Yukihiro Matsumoto writes: >まつもと ゆきひろです >|>世の中にある全部の拡張モジュールを書き換える必要があるわけで >|>すからできるだけAPIは変えたくないんですよねえ. >|この問題は解決してないですよね... > >こっちの問題が解決しないんで採用したくないんですよねえ. ですね. この問題も解決すると思われるいい案を考えました. 後方を参照して 下さい. >|# でも, 本来クラスが持つべき情報を持っていないところに問題があると思い >|# ますけどね. > >いや,まあそれをいえばその通りなんですけど,この情報ってこう >いう例外的な時にしか役に立たない情報なんですよねえ. 例外的というか... でも, どうにかしないと落ちますしね. Cレベルの問題で 落ちるのならいいですが, rubyレベルで落ちるのはまずいでしょう? >|現在オブジェクトに構造の情報が付加されるのは, >| OBJSETUP(obj, klass, type_id); >|のところですよね? このマクロ内で, >| klass->type_id != type_id >| >|だったら例外を発生させるというのはどうでしょう? 普通, type_idが異なっ >|ていたら, オブジェクトの構造に互換性がないと思って良いとおもうのですが... > >klass->type_id ってなに? クラスのTYPE()はいつも T_CLASS で >すけど.また,クラスの構造体にはインスタンスの type_id を格 >納するスペースは残ってないですし,またもし全てのオブジェクト >のサイズを拡大してそのスペースを用意したとしても,今度はいつ >どうやってインスタンスのtype_idを格納するか,という問題が残 >ります. この辺りの問題に触れない方法を考えました. 実現可能か検討して下さい. 何故, newを再定義するとまずいか? といいますと class String def String.new super end end の様にsuperを呼ぶのがまずいんですね. # finalの様にこのメソッドを再定義することがまずいんではないんです. これを分析しますと, String.newはそれなりの定義がCレベルで行なわれてい ます(それもsuperを使わず). これは何を意味しているかというと, 上位のク ラスとメソッドの互換性がないことを意味しています. 実は, このメソッドの定義によって上位クラスの同名のメソッドをオーバライ ドして隠蔽しているわけです. # もし隠蔽されなかったらundefするところでしょう. で, 解決案ですが, rb_define_singleton_method(cArray, "new", ary_s_new, -1) rb_define_method(cArray, "[]=", ary_aset, -1) の様にCレベルでメソッドが定義されたら, class Array super_undef new super_undef []= end の様に Arrayからは上位クラスのnew/[]=がundefされているようにみえるよう にすれば, 再定義されても全然問題がなくなります. で, 安全なメソッドのばあいは, class Exception super_redef new end の用に明示的にsuper.newが使えるように宣言するようにすれば良いと思いま す. この方法の利点は 1. finalの場合と違い再定義可能 class <> e-mail: keiju@rational.com <<---