Ruby局部变量范围

时间:2017-03-01 16:04:16

标签: ruby variables scope

我在红宝石中挣扎着变量范围。我的印象是局部变量可以通过它们下面的方法访问。查看以下代码,但我得到一个未定义的变量错误。

a = Array.new

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

testing

使用全局变量它可以正常工作,我怎样才能避免使用全局变量?

4 个答案:

答案 0 :(得分: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

它有效,因为代码是块而不是方法。

答案 1 :(得分: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"]

答案 2 :(得分:0)

您可以使用实例变量。名称以@开头的任何变量都是一个实例变量,并且可以在定义它的类或方法中的任何位置使用。例如,B类中定义的变量@A可用于B中的任何方法。

答案 3 :(得分: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一样使用块,或者使用它易于工作的方式。