[ruby-list:42984] 6.12 includeとextendはどう違いますか

From: take_tk <ggb03124@...>
Date: 2006-11-08 02:48:27 UTC
List: ruby-list #42984
たけ(tk)です

http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=FAQ%3A%3A%A5%AF%A5%E9%A5%B9%A1%A2%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB;em=include;em=extend#a6.2e12.20include.a4.c8extend.a4.cf.a4.c9.a4.a6.b0.e3.a4.a4.a4.de.a4.b9.a4.ab
6.12 includeとextendはどう違いますか
には
「includeはmoduleをクラス(モジュール)にインクルードして、メソッドを関数
形式で呼べるようにし、extendは moduleをオブジェクト(インスタンス)にイン
クルードして、メソッドを特異メソッドとして追加します。」
という説明しかないのですが、同じ名前のメソッドがある場合には顕著な違いが
あるようです。

次のような説明を追加してもらえませんでしょうか?

----
機能としては良く似ていますが、違いがでる場合もあります。たとえば、
モジュールとクラスで同じ名前のメソッドが定義されている場合には、顕著な違
いが現れます。

(1)      同じ名前のメソッドがある場合には、
(1-Inc)  includeではクラスで定義されたメソッドが呼ばれますが、
(1-Ext)  extendではモジュールで定義したメソッドが呼ばれます。

(2)      メソッド定義の中でsuperを呼び出した場合、
(2-Inc)  includeでは、
(2-Inc-C)クラスでのメソッド定義内のsuperはモジュールのメソッドを呼び出しますが、
(2-Inc-M)モジュールでのメソッド定義内のsuperはエラーになります。

(2-Ext)  extendでは、
(2-Ext-C)クラスでのメソッド定義内のsuperは(承継元のクラスに同名メソッ
ドがない限り)エラーになりますが、
(2-Ext-M)モジュールでのメソッド定義内のsuperはクラスで定義したメソッド
を呼び出します。

# include
module A
  def foo
    # super      #=> エラー (2-Inc-M)
    p :A_foo
  end
end
class B
  include A
  def foo      # ←       (1-Inc)これが呼ばれる
    super      #=> :A_foo (2-Inc-C)
    p :B_foo
  end
end
b = B.new
b.foo #=> :A_foo // :B_foo
----
# extend
module A
  def foo      # ←        (1-Ext)これが呼ばれる
    super      #=> :B_foo  (2-Ext-M)
    p :A_foo
  end
end
class B
  def foo
    # super      #=> エラー (2-Ext-C)
    p :B_foo
  end
end
b = B.new
b.extend A
b.foo #=> :B_foo // :A_foo


Take_tk = KUMAGAI Hidetake
たけ(tk)=熊谷秀武


In This Thread

Prev Next