From: shugo@... (Shugo Maeda) Date: 1998-03-07T21:29:10+09:00 Subject: [ruby-dev:1606] Re: [BUG] String.dup 前田です。 In message "[ruby-dev:1605] Re: [BUG] String.dup" 石塚圭樹 wrote: |何故, newを再定義するとまずいか? といいますと | | class String | def String.new | super | end | end | |の様にsuperを呼ぶのがまずいんですね. | |# finalの様にこのメソッドを再定義することがまずいんではないんです. そうですね。 僕もsuperを呼べないようにするにはどうすればいいか、というのは 考えたのですが、思いつきませんでした。 |で, 解決案ですが, | | 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されているようにみえるよう |にすれば, 再定義されても全然問題がなくなります. undefは rb_add_method(the_class, node->nd_mid, 0, NOEX_PUBLIC); のようにbodyが0になっている要素をそのクラスのメソッドテーブルに 挿入することで実現されているので、スーパークラスのメソッドがundef されているように見せるのは難しいのではないでしょうか。 そのクラスからのみスーパークラスのメソッドがundefされているように 見せるためには、クラスの中に各スーパークラスに対応したテーブルを すべて持たせる必要がありますよね。 # ちなみにundefはメソッドを消すわけではなくbodyが0のメソッドを # 定義するので、undef newした後にfinal :newとすると、newをundef # した上にnewの再定義ができなくなります。 |で. ここまで来て思ったのですが, undefは上記で出てきたsuper_undefの様な |定義とそのクラスに定義されているメソッドを消去する機能を合わせ持ってい |ますね? 2つに分離した方が良いと思います. undefにはsuper_undefの効果はありませんよね? rbc0> class << Foo rbc1> undef new rbc1> end nil rbc0> Foo.new NameError: undefined method `new' for Foo rbc0> class << Foo rbc1> def new; super end rbc1> end nil rbc0> Foo.new # rbc0> -- 前田 修吾