どちらの場合も自己は同じですか?
class Person
def who_am_i?
puts self # self?
end
end
ted = Person.new
def ted.singleton_who_am_i?
puts self # self?
end
ted.who_am_i?
ted.singleton_who_am_i?
はい、次のように表示されます。
class Person
def who_am_i?
puts self.to_yaml
end
end
ted = Person.new
def ted.singleton_who_am_i?
puts self.to_yaml
end
ted.who_am_i?
--- !ruby/object:Person {}
ted.singleton_who_am_i?
--- !ruby/object:Person {}
class Foo
def bar
p self
end
end
class << Foo
def bar
p self
end
end
Foo.bar #Foo (the class itself)
Foo.new.bar #<Foo:0x10acc70> (a Foo class object)
コンテキストがオブジェクト内にある場合、self がオブジェクトです。
コンテキストがクラス内にある場合、self がクラスです。
また、「シングルトン」が Ruby にとって適切な言葉であるかどうかもわかります。なぜなら、Ruby ではクラスでさえオブジェクトであり、「シングルトン」は既存のオブジェクトにメソッドを追加するだけだからです。
シングルトン メソッドは、特定のオブジェクトのみが応答するインスタンス メソッドです。これがどのように実装されるかは次のとおりです。
ここで明らかにされていないのは、実際のクラスとシングルトン クラスの間の実際の関係です。クラスとオブジェクトの間に位置していると言えます。
より正確には、シングルトン クラスは実際のクラスから継承され、実際にはオブジェクトのクラスです。
Object#class
シングルトン クラスを返さないのはなぜですか? まあ、それは単にそれをスキップします。ええ。
これが例です。次のクラスがあるとします。
class Person
def instance; self end # self is the Person instance here
end
person = Person.new
のシングルトン メソッドを定義したい場合はperson
、次のように記述できます。
class << person
def singleton; self end # What is self in this context?
end
これはこれとほぼ同等です:
class SingletonPerson < Person
def singleton; self end # self is the Person instance here too!
end
person = SingletonPerson.new
主な違いは、RubySingletonPerson
は がシングルトン クラスであることを認識しているため、呼び出したperson.class
ときに実際には getPerson
ではなくSingletonPerson
.
これにより、この複雑さがすべて効果的に隠されます。これは素晴らしいことです。ただし、物事が内部でどのように機能するかを理解することも素晴らしいことです。ここで同じロジックがクラス メソッドに適用されます。これは実際には、Class
またはModule
インスタンスのシングルトン メソッドです。