[#2023] Class Method の index — (Dezawa Shin-ichiro) <dezawa@...>

出沢です

13 messages 1997/02/02

[#2158] [Req] pack/unpack — keiju@... (Keiju ISHITSUKA)

けいじゅ@SHLジャパンです.

14 messages 1997/02/18
[#2166] Re: [Req] pack/unpack — matz@... (Yukihiro Matsumoto) 1997/02/18

まつもと ゆきひろです.

[#2277] ruby 1.0-970228 available — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです.

16 messages 1997/02/28

[ruby-list:2040] Re: [Req] no-name module (Re: [Request] static var?)

From: sinara@...
Date: 1997-02-04 06:33:26 UTC
List: ruby-list #2040
原です。

> |(4)無名のモジュール

> ちょうどextendに手を入れていたところでもあ
> るし,実装は全然むずかしくないので,undocumented featureとし
> て追加してみましょう.なお,この仕様は予告なく削除されること
> があります.

おー!ありがとうございます。


> うーん,これができてどのくらい嬉しいのかというとはなはだ疑問
> ではあるのですが,

もうちょっと説明します。そもそもはこういう事です。

特異メソッド:
  特定のオブジェクトに「一つ」のメッソッドをそのオブジェクトを
  レシーバとして「その場で」定義する。

extend:
  特定のオブジェクトに「複数」のメッソッドをそのオブジェクトを
  レシーバとして「どこかのモジュールで」定義する。

と整理できる。そこで形式的に

  特定のオブジェクトに「複数」のメッソッドをそのオブジェクトを
  レシーバとして「その場で」定義する。

という事が出来てもいいじゃないかと思いました。まあ、特異メソッ
ド並べればいいわけではありますが。^^;

具体的な例を一つでっちあげると、あるエリアに入って来たオブジェ
クトに通し番号をうつとしたら、ハッシュを使って

    hash[foo] = (counter += 1)

などとしますが、ここで extend が使えるなら

    foo.extend begin attr("serial_num", TRUE) end
    foo.serial_num  = (counter += 1)

などとできます。(前者だと番号の存在範囲は hash のスコープだ
けど、後者はオブジェクトの存在する限り、になっていいこともあ
ろうかと。)

特殊な例でしょうか。


> |include も出来てもいいかもしれない。
> 
> includeには不要でしょう.includeされるということはそもそも名
> 前付きクラス(モジュール)がそこに存在するということなので.

これは、

module Foo
  def foo() ... end
end

class C
  include Foo
end

と書くぐらいなら(そして Foo を再利用しないなら)、もともと

class C
  def foo() ... end
end

とかけるじゃないか?という意味でしょうか。そうでなかったら
以下の説明は意味ないですが(かなりくどいかもしれませんけど)
一応、説明します。

モジュールには、公式集の役割、Mixin の役割ともう一つ、メソッ
ドに継承関係をつけるというか「段差」をつける役割がありますよ
ね。例えば、クラス C でメソッド foo を定義したいだけなんだが、

(1)
class C
  def foo() ... end
end

と書かずにあえて直前のクラス B を作って

(2)
class B
  def foo() ... end
end

class C < B
end

とすることがあります。それはどういう時か(いよいよくどく
なるけど)説明すると、

C#foo を C と継承関係があったりなかったりする複数のクラス
E, F, G, ... で使っているとし、その foo を一斉に書きかえる
とします。例えば foo を

def foo
  prologue
  foo のオリジナル
  eplogue
end

に替えてしまいたい。このとき(2)の様に定義してあれば、
後で、

class C
  def foo
    prologue
    super
    eplogue
  end
end

と書き加える事で実現できるわけです。(1)の定義では super
で以前の foo を呼ぶ事はできません。エイリアスを使う方法
はありますが。

と、いうわけです。本当はオリジナルの C があるクラス A の
サブクラスなっている場合もあるので、(2)はモジュールで
書いた方がいいですね。こんな風に

(3)
module B
  def foo() ... end
end

class C < A
  include B
end

さて、この様な用途にモジュール B を使う時、B は再利用する
ことはあまり考えられないし、名前のバッティングもありえる
ので(クラス内モジュールとして隠蔽する手もあるが)、最初か
ら

(4)
class C < A
  include begin
    def foo() ... end
  end
end

と書けたら便利ではないでしょうか?

と、いうわけです。モジュールの本来の使い方ではないのかも
しれませんが。

#ここまで書いてさっき話題になったクラス Kernel の存在意義
#とかモジュール化の話と関連があることに気づきました。

In This Thread