class << selfクラスメソッドを宣言する方法以上のものです (ただし、そのように使用することはできます)。おそらく、次のような使用法を見たことがあるでしょう。
class Foo
class << self
def a
print "I could also have been defined as def Foo.a."
end
end
end
これは動作し、 と同等ですdef Foo.aが、その動作方法は少し微妙です。その秘密はself、そのコンテキストでは、 がオブジェクト を参照しFoo、そのクラスが の一意の匿名サブクラスであるということClassです。このサブクラスは固有クラスと呼ばれFooます。したがって、の固有クラスで呼び出される新しいメソッドを作成し、通常のメソッド呼び出し構文でアクセスできます: .def aaFooFoo.a
次に、別の例を見てみましょう。
str = "abc"
other_str = "def"
class << str
def frob
return self + "d"
end
end
print str.frob # => "abcd"
print other_str.frob # => raises an exception, 'frob' is not defined on other_str
最初はわかりにくいかもしれませんが、この例は最後の例と同じです。 frobは、Stringクラスではなくstr、 の一意の無名サブクラスである の固有クラスで定義されStringます。メソッドもそうですstrが、一般frobに のインスタンスはStringそうではありません。String のメソッドをオーバーライドすることもできます (特定のトリッキーなテスト シナリオで非常に役立ちます)。
これで、元の例を理解する準備が整いました。Fooの初期化メソッド内でselfは、 クラスFooではなく、 の特定のインスタンスを参照しFooます。その固有クラスは のサブクラスですFooが、そうではありませんFoo。そうでないと、2 番目の例で見たトリックが機能しません。例を続けるには:
f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)
f1.weasels = 4 # Fine
f2.monkeys = 5 # Also ok
print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method.
お役に立てれば。