【发布时间】:2017-07-21 01:29:18
【问题描述】:
我正在为 ruby 中的变量范围而苦苦挣扎。我的印象是局部变量可以通过它们下面的方法访问。查看以下代码,但我得到一个未定义的变量错误。
a = Array.new
def testing()
a.push("test")
end
testing
使用全局变量就可以了,如何避免使用全局变量?
【问题讨论】:
我正在为 ruby 中的变量范围而苦苦挣扎。我的印象是局部变量可以通过它们下面的方法访问。查看以下代码,但我得到一个未定义的变量错误。
a = Array.new
def testing()
a.push("test")
end
testing
使用全局变量就可以了,如何避免使用全局变量?
【问题讨论】:
这里没什么好说的,除了 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
它可以工作,因为代码在块中而不是方法中。
【讨论】:
您可以使用实例变量。任何名称以 @ 开头的变量都是实例变量,并且在定义它的类或方法中的任何位置都可用。例如,在 B 类中定义的变量 @A 将可用于 B 中的任何方法。
【讨论】:
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的答案那样使用块,或者使用它容易工作的方式。
【讨论】:
在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'
显然,这不起作用。第一个a 是class 主体范围内的局部变量,而第二个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"]
【讨论】: