4

我将一个类分配给一个常量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

为什么是这样?

4

3 回答 3

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"

将其分配给 contant Foo,就像:

Foo = Class.new
Foo.name
# => "Foo"

它还设置了它的name,但这并不能使它成为一个类。您也可以创建没有名称的类:

foo = Class.new
foo.name
# => nil

将未命名的类分配给常量会设置其名称:

Bar = foo
foo.name
# => "Bar"

一旦设置,它就不会改变:

Baz = foo
foo.name
# => "Bar"
于 2013-05-13T16:22:59.027 回答
2

您创建的类存在并且可以从主 ObjectSpace 访问,只要它没有被垃圾回收。

常量名Foo只是对类对象的引用。它的内部名称仍然是“Foo”,即使通过其他变量或常量名称访问。

试试这个,以证明即使 'renamed' a,类的名称仍然是“Foo”:

class Foo; end
a = Foo
Foo = nil
puts a.name # prints Foo
于 2013-05-13T15:21:52.883 回答
1

Foo绑定到nil,在块的内部和外部。是什么让你认为不是?您甚至没有指Foo块内部。

于 2013-05-13T15:25:56.340 回答