2013-05-13 104 views
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 

這是爲什麼?

+0

這來自JörgW Mittag對我對[這個問題]的回答的評論(http://stackoverflow.com/questions/16523676)。 – sawa 2013-05-13 15:18:50

回答

4

將常量Foo指定爲nil不會影響創建的類。它仍然存在,儘管您不能再使用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" 
+0

我明白了。我似乎混淆了常量「named」'Foo'和一個'name'屬性是'Foo'的類。謝謝您的幫助。 – sawa 2013-05-13 17:09:40

2

您創建的類存在並可從主ObjectSpace訪問,只要它不被垃圾收集即可。

常數名稱Foo僅僅是對類對象的引用。它的內部名稱仍然是「Foo」,即使通過其他變量或常量名稱訪問。

試試這個,證明甚至「更名爲」 a,類的名字仍然是「富」:

class Foo; end 
a = Foo 
Foo = nil 
puts a.name # prints Foo 
+0

這是否意味着兩個不同的對象可以共享相同的名稱,並且有某種優先級決定使用該名稱調用時引用哪個對象? – sawa 2013-05-13 15:34:32

+0

這裏只有一個對象。 – 2013-05-13 15:36:45

+0

我提到'nil',它被稱爲'Foo',和原來的類對象,它也有'Foo'這個名字。 – sawa 2013-05-13 15:40:14

1

Foo勢必nil,內外塊之外。是什麼讓你覺得它不是?您甚至不提及塊內的Foo

+0

塊內的對象返回'Foo'作爲其名稱,這是一個類。 – sawa 2013-05-13 15:27:15

+0

這與常量「Foo」的值有什麼關係? – 2013-05-13 15:29:25

+0

大寫的名字是一個常量。 – sawa 2013-05-13 15:31:12

相關問題