2012-06-01 59 views
0

我正在學習符號,我很驚訝地發現文件中的所有符號都包含在Symbol.all_symbols數組中,當我將它轉儲爲第一行時我的文件。 但是,如果我嘗試訪問進一步定義的類,我得到NameError,換句話說它是一個無法識別的符號。Ruby類名稱在符號列表中,但不被翻譯人員識別

puts "DefinedAtEnd is in symbol list: \ 
#{Symbol.all_symbols.select {|s| s =~ /^DefinedAtEnd/} != nil} " 
puts "do_it is in symbol list: \ 
#{Symbol.all_symbols.select {|s| s =~ /^do_it/} != nil} " 
puts "foo is in symbol list: #{Symbol.all_symbols.select {|s| s =~ /^foo/} != nil} " 

#d = DefinedAtEnd.new # This will get a NameError 

class DefinedAtEnd 
    def do_it 
    foo = 'bar' 
    puts 'In method do_it' 
    end 
end 

上述運行得到這樣的結果:

DefinedAtEnd is in symbol list: true 
do_it is in symbol list: true 
foo is in symbol list: true 

但是,如果我取消對該行d = DefinedAtEnd.new然後我得到了以下錯誤:

uninitialized constant DefinedAtEnd (NameError) 

似乎解析器(metparser? )在開始「執行」代碼行之前解析整個文件一次,但尚未構建類。也許這是某種'預傳'?

回答

1

有解析源文件和執行它的代碼之間的差。它發生在兩個階段。在解析過程中,對象的名稱(包括類名稱和理論上可能分配的所有變量)將被插入符號表中。也就是說,這是一個你可能不應該依賴的實現細節(甚至更多,因爲你不能真正做出有用的東西)。

通常,符號是interned字符串,即從不被垃圾回收的字符串,並且在整個解釋器中只存在一次。

"foo".object_id == "foo".object_id # => false 
:foo.object_id == :foo.object_id  # => true 

與字符串不同,符號也不能改變的地方,它們是不可變的。

+0

**解析**與**執行**(解釋) - 這是關鍵。謝謝。 – Will

1

該文件逐行解釋;你不能在代碼中引用還沒有定義的東西 - 被讀取與初始化不同。

紅寶石1.9.2輸出以下,這可能是一個以上位的照明:

foo2.rb:7:in `<main>': uninitialized constant Object::DefinedAtEnd (NameError) 
+0

是的,我現在更瞭解一點。我已經用'defined?'操作符添加了測試,正如您所指出的那樣,對於類的前向引用在解釋器方面還沒有定義。但符號表中的符號**爲**。所以這確實意味着解釋器正在做一些第一遍**讀取**文件並構建符號表。 – Will

相關問題