是否有可能以某种方式访问Class.new范围内的a
?
a = 5
Class.new{ def b; a end }.new.b
# NameError: undefined local variable or method `a' for #<#<Class:0x007fa8b15e9ca8>:0x007fa8b15e9af0>
# :in `b'
答案 0 :(得分:7)
即使@MarekLipka答案是正确的 - 改变变量范围总是有风险的。这是有效的,因为每个块都带有它创建的上下文,因此你的局部变量a
突然不是本地的 - 它变成了一个隐藏的&#39;全球:
a = 5
object = Class.new { define_method('b') { a } }.new
object.b #=> 5
a = 4
object.b #=> 4
如果你想通过引用传递不可复制的变量(这实际上与javascript闭包非常相似),这自然很有用,但是在大多数情况下它会引入极难调试的bug:
a = 5
object = Class.new { define_method('b') { a = a + 1 } }.new
object.b
a #=> 6
使用实例变量更加清晰:
a = 5
Class.new do
def initialize(a)
@a = a
end
def b
@a
end
end.new(a).b #=> 5
答案 1 :(得分:5)
您可以使用define_method
代替def
关键字并将块传递给它(块是闭包,因此它保留对a
的引用):
a = 5
Class.new { define_method('b') { a } }.new.b
# => 5
答案 2 :(得分:-1)
你可以把'a'作为全局变量
$a = 5
Class.new{ def b; $a end }.new.b