2012-03-12 105 views
34

我有以下Ruby代碼:Ruby的局部變量是未定義

local_var = "Hello" 

def hello 
    puts local_var 
end 

hello 

我收到以下錯誤:

local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' 
for main:Object (NameError) from local_variables.rb:7:in '<main>' 

我始終認爲,局部變量不能從塊的外部訪問,功能,關閉等

但是現在我在文件中定義了局部變量並嘗試從函數中獲取一個訪問INSIDE s ame文件。

我的理解有什麼問題?

+1

你說過「我一直認爲局部變量不能從[...]函數外部訪問」。那麼,爲什麼你感到驚訝,你的本地變量只在'puts'行的函數內部尋找? – Gareth 2012-03-12 17:15:40

+4

,因爲其他編程語言不同 – shevchyk 2012-03-12 19:36:21

+1

試試@local_var =「你好」 – 2016-01-18 22:56:00

回答

51

在Ruby中局部變量只能在它們定義的範圍內訪問。每當你進入/離開一個類,一個模塊或一個方法定義你的範圍在Ruby中改變。

例如:

v1 = 1 

class MyClass # SCOPE GATE: entering class 
    v2 = 2 
    local_variables # => ["v2"] 

    def my_method # SCOPE GATE: entering def 
    v3 = 3 
    local_variables # => ["v3"] 
    end # SCOPE GATE: leaving def 

    local_variables # => ["v2"] 
end # SCOPE GATE: leaving class 

這些進出點,被稱作範圍蓋茨。由於您通過方法定義通過Scope Gate進入,因此您無法在hello方法中訪問您的local_var


您可以使用Scope Flattening概念將變量傳遞給這些門。

例如,如果不使用def來定義您的方法,則可以使用Module#define_method

local_var = "Hello" 

define_method :hello do 
    puts local_var 
end 

在你可以定義通過Class#New你的類,這樣當你通過類定義的範圍不改變以同樣的方式。

local_var = 'test' 

MyClass = Class.new do 
    puts local_var #valid 
end 

代替

class MyClass 
    puts local_var #invalid 
end 

如果您想通過模塊門來傳遞你的局部變量,你應該使用Module#New以同樣的方式。

實施例從Metaprogramming Ruby

-7

local_var採取是一個局部變量。局部變量對於它們被定義的範圍是局部的(這就是爲什麼它們是畢竟叫做「局部變量」)所以,很明顯,因爲local_var在腳本範圍中定義,所以不能在方法範圍中訪問它。

+20

如果我在一輛汽車裏,而且我的口袋裏有了變化,那麼汽車就會有變化。許多其他語言將局部變量轉發到內部作用域,所以沒有理由把Ruby的行爲看作是自明的。 – 2014-04-01 19:44:27

+0

@AdamTolley你是完全正確的,但我猜Ruby可能是Jorg的第一語言,並且範圍對他來說可能是顯而易見的! – 2017-03-03 10:56:24

+0

@AlexanderSuraphel:實際上,這是關於我的第十五種語言,雖然在我寫這個答案的時候,我可能還有十多個。我沒有真正跟蹤。 – 2017-03-03 15:07:02

相關問題