[ruby-list:47941] Re: 特異クラス、特異メソッド

From: "KISHIMOTO, Makoto" <ksmakoto@...4u.or.jp>
Date: 2011-03-08 11:22:20 UTC
List: ruby-list #47941
きしもとです

ちょっとソースコードは整形させてもらいますが、

class MyClass
  class << self
    # ここは MyClass の特異クラス
  end|
end

obj = MyClass.new
class << obj
  # ここは obj の特異クラス
end

> 例えば、上記のようなMyClassのオブジェクトが複数あった場合に
> そのオブジェクトごとに挙動を変えるとか、そういう意味あいの
> ことなのでしょうか?

基本的には、そういったことのために使われています。

別の例で順番に説明していきますが、

#==== 例 1 ここから
obj1 = Object.new

def obj1.foo
  p "this is obj1"
end

obj1.foo

obj2 = Object.new

class << obj2
  def foo
    p "this is obj2"
  end
end

obj2.foo
#==== ここまで

実行すると、
"this is obj1"
"this is obj2"
と出力されます。

Object#foo というメソッドはないわけで、def obj1.foo によって、
変数 obj1 の指すインスタンスだけのメソッドを定義して、呼んでいる
わけです。このようなメソッドを「特異メソッド」と言います。

同じことを、class << という記法を使って、やっているのが例 1 の後半で、
特異メソッドが定義されるのは、実は、「特異クラス」という、個々の
インスタンス専用のクラスなのですが、class << obj2 で、変数 obj2 が
指すインスタンスの、特異クラスを引っ張り出して、そこに foo を
定義しています。

続きます。

#==== 例 2 ここから
module Mod1
  def self.bar
    p "this is Mod1.bar"
  end
end

Mod1.bar

module Mod2
end

class << Mod2
  def bar
    p "this is Mod2.bar"
  end
end

Mod2.bar
#==== ここまで

実行すると、
"this is Mod1.bar"
"this is Mod2.bar"
と出力されます。

例 2 の前半は、多分この例の中にあるものの中で、普通の Ruby
プログラミングにおいて一番一般的なものではないかと思いますが、
モジュールの特異メソッドです。「クラスメソッド」と呼ばれたりも
します。

例 2 の後半は、例 2 の前半と同じことを class << obj の記法を
使って、やっています。

例 1 と例 2 で、同じパターンになっていますが、Ruby の
クラスメソッドが、どういう仕掛けでできているか、対応付けて
見てみるとわかるのではないか、と期待したいのですが……

In This Thread