nil
,false
,true
的单例类与定制类的实例之间似乎存在对比。
i)nil
,false
和true
的单例类由它们分配的常量名称引用:
nil.singleton_class #=> NilClass
false.singleton_class #=> FalseClass
true.singleton_class #=> TrueClass
ii)nil
,false
和true
的单例类出现在祖先列表中:
nil.class.ancestors #=> [NilClass, Object, Kernel, BasicObject]
false.class.ancestors #=> [FalseClass, Object, Kernel, BasicObject]
true.class.ancestors #=> [TrueClass, Object, Kernel, BasicObject]
对于自定义类AClass
的实例a
的名为A
的单例类,
class A; end
a = A.new
AClass = a.singleton_class
i)AClass
未被其分配的常量名称引用:
a.singleton_class #=> #<Class:#<A:0x00007fda832a7eb0>>
ii)AClass
未出现在祖先列表中:
a.class.ancestors #=> [A, Object, Kernel, BasicObject]
这是预期的行为吗?一方面分隔nil
,false
,true
和另一方面a
的原因是什么?该规范的依据是什么?
答案 0 :(得分:2)
不确定是否有帮助,但可以从docs for singleton_class
进行:
如果obj是
nil
,true
或false
,则分别返回NilClass
,TrueClass
或FalseClass
。
因此singleton_class
对于nil
,true
和false
具有特殊的行为,而不是返回对象的单例类的标准行为。
答案 1 :(得分:2)
1。 nil
,false
,true
个对象
i)nil,false和true的单例类由引用 他们分配的常量名称:
这是不正确的。 singleton_class
,nil
和true
的{{1}}方法不返回其单例类,因为它们不存在。而是返回其实际类。这些对象没有单例类的原因很明显,并在@zeitnot的答案中进行了很好的描述。
此行为是预期的,并在https://ruby-doc.com/core/Object.html#method-i-singleton_class
中进行了记录ii)nil,false和true的单例类出现在祖先上 列表
这也不正确。由于这些对象没有单例类,因此您在祖先列表中看到的是它们的实际类。但是,即使他们有单例课程,您也不会通过这种方式获得它们(继续阅读以了解原因)
2。自定义类false
的实例a
i)AClass没有通过其分配的常量名称来引用:
A
此代码使AClass = a.singleton_class
引用AClass
。但这是单向关系(从a.singleton_class
到AClass
)。它并没有使a.singleton_class
引用并返回a.singleton_class
。
ii)AClass没有出现在祖先列表中:
要获取包括单例类的祖先列表,请执行AClass
而不是a.singleton_class.ancestors
。
a.class.ancestors
a.singleton_class.ancestors #=> [#<Class:#<A:0x000000000191dba0>>, A, Object, Kernel, BasicObject]
方法仅查找层次结构:
ancestors
答案 2 :(得分:1)
一个很好的例子经常说出很多话:
require 'singleton'
class FooClass
include Singleton
alias singleton_class class
def inspect
'foo'
end
end
现在让我们看一下相似之处:
true #=> true
true.class #=> TrueClass
true.singleton_class #=> TrueClass
foo = FooClass.instance # unfortunately the syntax is not exactly the same
foo #=> foo
foo.class #=> FooClass
foo.singleton_class #=> FooClass
这意味着true.singleton_class
是指其自己的类而不是其单例类。这是有道理的,因为true
是一个单例,它使自己的类成为每个定义的单例类。 (因为它是单例的类。)
答案 3 :(得分:0)
在红宝石中,NilClass
,FalseClass
和TrueClass
只能有一个实例。因此,这就是为什么他们没有singleton_class
的原因。
例如:
a = nil
def a.foo
'foo'
end
b = nil
b.foo => # foo
我们可能会看到,即使我们为变量b
定义了foo
方法,foo
也会响应foo
方法并返回a
字符串。这意味着这3个类只能有一个实例。还有另一件事要指出,nil
,false
和true
是变量,只是伪变量。不能为它们分配不同的数据结构。从某种意义上说,它们是冻结变量。