2013-04-03 67 views
3

我想弄清楚的Ruby如何處理具有相同的名稱爲self類的方法的局部變量,並發現了一個行爲,我不明白:方法的局部變量同名的另一種方法

class A 
    def val 
    10 
    end 

    def test 
    val = val 
    end 
end 

p A.new.test 

此代碼打印nil。爲什麼?!

+0

方法'val'是一個紅色的鯡魚。你從來沒有真的叫它。 –

+0

類似的方法和它內部的變量具有相同的名稱:http://stackoverflow.com/questions/8174019/what-happens-with-this-method-name-local-variable-mixing,外部變量:http: //stackoverflow.com/questions/3741582/method-and-variable-name-is-the-same –

回答

3

我認爲局部變量一旦被聲明就會被聲明。在ruby中,查找首先查找局部變量,如果它存在,則使用該變量,否則查找方法。這意味着,VAL = VAL宣佈第一VAL當地和左手VAL然後與它匹配(不知道它,我應該檢查ruby under microscope,以確保)

如果您嘗試

class A 
    def val 
    10 
    end 

    def test 
    back = [] 
    x = val 
    back << x 
    val = x + 1 
    back << val 
    x = val 
    back << x 
    end 
end 

p A.new.test 

那麼一切都很好,它會打印[10,11,11],這意味着第一個x = val調用該方法,第二個調用局部變量,據推測。

+0

謝謝。這是一個合理的解釋。它也解釋了爲什麼它不會在'val = val'中引發異常。 – akonsu

0

這是nil,因爲val是你試圖傳遞的方法,你不會在任何地方調用val,並且它會覆蓋自身。基本上你陷入循環。

在每個函數的末尾有一個隱式返回,它返回最後一個值,如果它沒有返回值,Ruby返回nil,但是你可能期待一個函數?

這與Python類似,其中沒有返回的函數總是返回None

這可以通過將的內涵將左手val轉換爲實例屬性來解決。

我猜你想要它打印10使用val()方法?

def test 
    @val = val() 
end 

puts A.new.test 

下面是同樣有效:

def test 
    val = self.val() #but this will produce the same as above to no real benefit. 
end 

,關鍵在於你必須調用val方法,以使val變量來獲取值。

+0

謝謝。我不會說我因爲程序終止而陷入循環。我期待'10',而不是一個功能。這肯定與括號有關。如果我的'test'方法只有一行'val',那麼它返回'10'。但對我來說,令人困惑的部分是這項任務導致'val'成爲'nil'。 – akonsu

+0

不是,它更多的是與你試圖告訴Ruby「val」本身有關。這導致了Ruby無法找出你想要的循環。 –

+0

沒有循環。該程序終止。我很困惑。 – akonsu

0

這應分成兩個問題:

  1. 當你a = a,什麼是第一次評估?如果你做echo 'p a = a' | ruby,你會得到nil,而不是未定義的異常,所以定義是第一位的。

  2. 當局部變量與方法名稱相同時會發生什麼?答案:除非您使用方法,否則方法變得不可見self.

相關問題