2017-03-01 152 views
0

我在Ruby變量中掙扎。我的印象是局部變量可以通過它們下面的方法訪問。看看下面的代碼,但是我得到一個未定義的變量錯誤。Ruby本地變量範圍

a = Array.new 

def testing() 
    a.push("test") 
end 

testing 

使用全局變量它工作得很好,我該如何避免使用全局變量?

回答

4

除了Ruby中的局部變量只能在定義它們的作用域和在該作用域中定義的任何塊(閉包)中捕獲它們之外,沒有什麼可說的。由於在Ruby中,與其他一些動態語言不同,方法不是閉包,它們不捕獲局部變量。

如果你試過了,說,這:

irb(main):001:0> a = 3 
=> 3 
irb(main):002:0> define_method(:testing) do 
irb(main):003:1* puts a 
irb(main):004:1> end 
=> :testing 
irb(main):005:0> testing 
3 

它的工作原理,因爲代碼是在一個塊,而不是一個方法。

0

您可以使用實例變量。任何名稱以@開頭的變量都是一個實例變量,並且可以在定義它的類或方法中的任何地方使用。例如,B類中定義的變量@A將提供給任何方法B.

0
2.3.3 :007 > def testing() 
2.3.3 :008?> [].push("test") 
2.3.3 :009?> end 
=> :testing 
2.3.3 :010 > testing 
=> ["test"] 

你不能讓局部變量通過如下它們的方法訪問,您可以使用塊像由@Linuxios答案,或者用簡單的方式工作。

1

top-level中定義方法可能會相當混亂。讓我們來包裝你的代碼在一個類來代替:

class Foo 
    a = [] 

    def testing 
    a << 'test' 
    end 
end 

通過(我已經縮短Array.new[]a.push(...)a << ...

Foo#testing可以稱爲:

foo = Foo.new 
foo.testing 
#=> undefined local variable or method `a' 

顯然,這並未沒有工作。第一個aclass正文範圍內的局部變量,而第二個a是實例方法中的局部變量。

移動變量初始化出來的類主體的入initialize方法也不管用,因爲局部變量是不能跨越的方法共享:

class Foo 
    def initialize 
    a = []   # <- one 'a' 
    end 

    def testing 
    a << 'test' # <- another 'a' 
    end 
end 

得到這個工作,你必須使用一個實例變量

class Foo 
    def initialize 
    @a = [] 
    end 

    def testing 
    @a << 'test' 
    end 
end 

foo = Foo.new 
foo.testing 
#=> ["test"] 

foo.testing 
#=> ["test", "test"]