在这两种情况下 self 是否相同?
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 {}
单例方法是只有特定对象响应的实例方法。这是如何实现的:
这里不明显的是实际类和单例类之间的实际关系。可以说它位于类和对象之间。
更准确地说,单例类继承自实际类,实际上是对象的类。
你问为什么不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
主要区别在于 Ruby 知道这SingletonPerson
是一个单例类,因此当您调用时,person.class
您实际上是 getPerson
而不是SingletonPerson
。
这有效地向您隐藏了所有这些复杂性,这是一件好事。但是,了解事物在幕后的运作方式也很棒。这里同样的逻辑适用于类方法,它们实际上只是 aClass
或Module
实例的单例方法。
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 就是类。
我也知道“singleton”对于 Ruby 来说是否是一个好词,因为在 Ruby 中,甚至一个类也是一个对象,而“singleton”只是将方法添加到现有对象。