Ruby では、既存のクラスを再度開いてメソッドを追加できます。つまり、次のように言えます。
class Foo
def bob
return "hello from bob"
end
end
これらのメソッドは、クラスの内部ディクショナリ (おそらくインスタンス変数) のどこかに格納されますFoo
(これはクラスの単なるインスタンスでありClass
、したがってインスタンス変数を持ちます)。
しかし驚くべきことは、既存のオブジェクトのインスタンスにメソッドを追加することもできるということです
foo = Foo.new
foo2 = Foo.new
def foo.fred
return "I am fred"
end
foo.fred #=> "I am fred"
foo2.fred #=> NoMethodError
しかし、このメソッドは実際にどこに保存されていますか?
Ruby は舞台裏で新しいクラス ( singleton class、metaclass、またはeigenclassと呼ばれることもあります) を作成し、 -classとそのインスタンスの間の継承階層に挿入されます。Foo
したがって、継承関係は次のようになります。
foo < (eigenclass of foo) < Foo < Class
(foo.superclass と言うと、シングルトン クラスは表示されません)
-syntax は、この特別なクラスを取得する方法であり、class << X
直接操作できます。次のコード ブロックはまったく同じです。
def foo.bar
return "xy"
end
# is exactly the same as
class << foo
def bar
return "xy"
end
end
したがって、 と の類似性は偶然class Foo < Bar
でclass << Foo
はなく、両方で継承が行われています。
class << X
「X のメタクラスを開く」と考えてください。
Ruby で覚えておくべきことは、クラス自体は単なるオブジェクトだということです。(クラスのインスタンスClass
)だから、あなたが言うなら:
class Foo
class << self
def k
return "x"
end
end
end
(このコード ブロックでself
は にバインドされています) も の固有クラスのインスタンス メソッドであり、これにより のクラス メソッドになります。Foo
k
Foo
Foo
これはすべて、つるはしのクラスに関する章でより明確に説明されています (残念ながら、Web バージョンには図が含まれていません)。