2012-09-27 50 views

回答

13

這是因爲Ruby解析器的工作原理。變量由解析器定義,解析器逐行遍歷代碼,而不管它是否會被實際執行。

一旦解析器看到x =,它就會在當前範圍內定義本地變量x(值爲nil)。由於if/unless/case/for/while不會創建新的示波器,因此x已在代碼塊外定義並可用。並且由於內部塊從未被評估爲條件爲假,所以x未被分配給(並且因此是nil)。

這裏有一個類似的例子:

defined?(x) and x = 0 
x #=> nil 

請注意,這是發生了什麼相當高層次的概述,而不一定究竟是如何解析的作品。

+0

啊,打我吧。很好的解釋。 – nneonneo

2

這與Ruby的範圍規則的怪癖有關。

在ruby中,一個不帶變量的變量x本身可以是局部變量或方法調用 - 語法不能分辨哪個變量。由解析器解析局部變量引用,由解析器決定。規則很簡單:如果已經在本地範圍中看到對同名變量的分配,則引用是局部變量,並且引用被綁定到該局部變量。否則,這是一個方法調用,它將在運行時被查找。

Ruby中的局部變量引用在數組查找中進行了優化(每個局部變量都分配了一個'slot',並且分析器生成的綁定局部變量引用被轉換爲槽引用)。該陣列被初始化爲所有nil

/* initialize local variables */ 
for (i=0; i < local_size; i++) { 
    *sp++ = Qnil; 
} 

因此,如果你指的是沒有被分配的局部變量,通過一個綁定本地引用(如果有基準上述跳過的分配只能發生在相同的本地範圍內),您將獲得nil

1

我覺得你的問題很有意思,所以我想看看它,並發現這一點: I don't understand ruby local scope

正確的答案似乎是把約爾格。

讓我們看看會發生什麼,當您嘗試訪問未初始化的變量:

NameError: undefined local variable or method `UNDECLAREDVAR' for main:Object 

的異常狀態,這是無法評估是否變量或方法。它不拋出相同異常的原因是因爲未初始化的局部變量被設置爲nil。所以puts x是好的,因爲口譯員知道x是可變的但未初始化,而不是一種方法。

相關問題