ごとけんです

In message "[ruby-list:12002] What's DelegateClass ? (Re: how to make class?)"
    on 99/02/11, "Kikutani, Makoto" <kikutani / sprintmail.com> writes:

>> >「rubyの匠な人々はどうやってクラスを作るんでしょうか?」
>> 匠でなくて申し訳ありませんが,面白そうなんで,ぼくの場合(^^;;
>だめっすよ嘘ついちゃ >ごとけんさん

いやマジでセンス悪いし,マニュアルみるたびに発見があったり…
# 「みるたび」は言いすぎか (^^;;

>だいたい DelegateClass って何?

たとえば,

  class A < Array
    def foo;
      @bar = 'spam'; 
    end

    attr_reader :bar
  end

  a = A.new
  a.foo
  p a.bar

を実行すると

../dele.rb:3:in `foo': class A can not have instance variables (TypeError)
        from ../dele.rb:10

というエラーが返ってきます.これは組み込みクラスとそのサブクラス
はオブジェクトのサイズを抑えるなどの理由でインスタンス変数をもて
ないようになっているためです.

で,これに対する解決法として DelegateClass を使うことができます.

  require "delegate" 

  class A < DelegateClass(Array)
    def foo;
      @bar = 'spam'; 
    end

    attr_reader :bar
  end

  a = A.new([])
  a.foo
  p a.bar

を実行すると,ちゃんと "spam" と出力されます.
A は Array のサブクラスではありませんが,Array と機能は同じです.

上の A の initialize は適当に再定義したほうが良さげです.
デフォルトでは,デレゲートを任されるクラスのオブジェクトを
与えることになっています.new の引数に [] がついてるのは
そのためです.もとの Array と同じにするなら,こんな感じ:

  def initialize(s=0 , v=nil)
    super(Array.new(s, v))
  end

また,よく使うクラスなら DelegateClass で作ったのをじっと
見つめて必要な部分だけ抜きだして普通のクラスとして再構成
したほうが実行効率はあがるかも知れません.

>ruby-man-1.2-jp や ruby-uguide の下で grep -i delegate * しても
>あたらないじゃないですか。delegateという用語は tkscrollbox.rb
>の例を昔まつもとさんが説明してくれたけど、実はよくわかってない。
>しかも、1.0のころにはなかった delegate.rb などというものが
>いつのまにかある。

ですね,これは使いでがあるので何かドキュメントがあったほうが
よいかも.

ちなみに delegate というのはデザインパターンとかいう世界の
ことばらしいですが,僕は詳しくは知りません.匠ぢゃないし (^^;;

-- gotoken