Ruby 为什么没有';是否定义了引用相同名称的实例变量?
我在代码中遇到了一个奇怪的bug,它揭示了ruby的一个有趣行为。希望有人能解释它为什么会这样 我有一个带有实例变量@foo的类和一个引用局部范围变量foo的方法。我意外地重构了方法的一部分,留下了对foo的引用;变量不再在范围中定义。它最终指向@foo。更改foo会更改@foo,反之亦然 简化版: 编辑:添加iAutofNamesRuby 为什么没有';是否定义了引用相同名称的实例变量?,ruby,scope,scope-resolution,narwhal,Ruby,Scope,Scope Resolution,Narwhal,我在代码中遇到了一个奇怪的bug,它揭示了ruby的一个有趣行为。希望有人能解释它为什么会这样 我有一个带有实例变量@foo的类和一个引用局部范围变量foo的方法。我意外地重构了方法的一部分,留下了对foo的引用;变量不再在范围中定义。它最终指向@foo。更改foo会更改@foo,反之亦然 简化版: 编辑:添加iAutofNames class ImOutOfNames attr_accessor :foo # the culprit! end class Bar < ImOut
class ImOutOfNames
attr_accessor :foo # the culprit!
end
class Bar < ImOutOfNames
def initialize
@foo = "that is a tasty burger"
end
def bar_method_1
foo = "Come on Yolanda, whats Fonzie like?"
bar_method_2
end
def bar_method_2
puts foo
end
end
我甚至让一位更资深的开发人员来看一看,他有些困惑,并证实了这一行为
这是一种预期的行为,我误解了@variables的工作原理,还是有什么问题?您的@foo实例变量是否有attr访问器?这是一种可能发生的方式 一般来说,我建议不要对局部作用域变量使用相同的名称,但您可以发现它是否来自具有
self.method(:foo)
或者如果它是用
defined? foo
利用ruby运行时无疑会减少某些代码的神秘性和神奇性。您以前的错误代码可能位于attr\u访问器定义中,该定义创建了访问实例变量的方法foo 如果您的代码如下所示,则可以具有相同的行为:
class Bar
attr_accessor :foo
def initialize
@foo = "that is a tasty burger"
end
def bar_method_1
foo = "Come on Yolanda, whats Fonzie like?"
bar_method_2
end
def bar_method_2
puts foo
end
end
attr_访问器调用在对象中定义了两个方法
def foo
@foo
end
def foo=(value)
@foo = value
end
因此,在您的案例中,当没有定义局部变量时,使用了该方法,但在本例中,由于您没有调用attr\u accessor,您发布的方法没有定义,并且在bar\u method\u 2上没有可使用的局部变量,因此调用失败。非常奇怪。没有一个
attr\u阅读器:foo
藏在那里的某个地方,是吗?你没有误解什么。如果def foo@未定义foo end
(显式或通过attr\u reader
或attr\u accessor
),foo
不应返回@foo
啊哈!我刚检查过,确实有一个attr_访问器:foo.nice:)我得看看那些神奇的方法。将其中一个答案与一个要点联系起来:-PI没有足够的声誉来给分数:(这很有意义,谢谢!我回去检查了一下,发现它的父类中有一个attr_访问器。
def foo
@foo
end
def foo=(value)
@foo = value
end