我将一个类分配给常量Foo
,并将Foo
重新分配给其他内容:
class Foo; end
Foo = nil
在main
环境中,Foo
指的是新分配的对象:
p Foo # => nil
但是,在某种迭代中,(我不确定是哪种),Foo
引用了前一个对象:
ObjectSpace.each_object(Class).select{|c| c.name == "Foo"}
.each{|c| p c, c.instance_of?(Class)}
# => Foo
true
为什么会这样?
答案 0 :(得分:4)
将nil
分配给常量Foo
不会影响创建的类。它仍然存在,但您不能再使用Foo
引用它(除非您再次将类对象重新分配给Foo
)。
class Foo; end
Foo.object_id
# => 70210590718440
Foo = nil
Foo.object_id
# => 4
Foo = ObjectSpace._id2ref(70210590718440)
Foo.object_id
# => 70210590718440
关于name
,创建一个类:
class Foo; end
Foo.name
# => "Foo"
将其分配给内容Foo
,就像:
Foo = Class.new
Foo.name
# => "Foo"
它还设置了name
,但这不会使它成为一个类。您也可以创建没有名称的类:
foo = Class.new
foo.name
# => nil
将未命名的类分配给常量设置其名称:
Bar = foo
foo.name
# => "Bar"
设置后,它不会改变:
Baz = foo
foo.name
# => "Bar"
答案 1 :(得分:2)
您创建的类存在且可以从主ObjectSpace访问,只要它不是垃圾回收。
常量名Foo
仅仅是对类对象的引用。即使通过其他变量或常量名称访问,其内部名称仍为“Foo”。
试试这个,为了证明即使'重命名'a
,该类的名称仍然是“Foo”:
class Foo; end
a = Foo
Foo = nil
puts a.name # prints Foo
答案 2 :(得分:1)
Foo
绑定到nil
,在块的内部和外部。是什么让你认为不是?您甚至没有在块内引用Foo
。