这两种情况下,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 {}
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"只是将方法添加到现有对象。
单例方法是只有某个对象响应的实例方法。以下是实现方式:
- 打开对象的单一实例类;
- 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
主要区别在于 Ruby 知道 SingletonPerson
是一个单例类,所以当你调用person.class
时,你实际上会得到Person
而不是SingletonPerson
。
这有效地向您隐藏了所有这些复杂性,这是一件好事。但是,了解引擎盖下事物的运作方式也很棒。此处相同的逻辑适用于类方法,类方法实际上只是Class
或Module
实例的单例方法。