[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 の
クラスメソッドが、どういう仕掛けでできているか、対応付けて
見てみるとわかるのではないか、と期待したいのですが……