2017-03-01 164 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"]