为什么尚未定义的局部作用域变量会引用同名的实例变量?
我在代码中发现了一个奇怪的错误,它揭示了 ruby 的一个有趣的行为。希望有人能解释为什么它会这样。
我有一个带有实例变量 @foo 的类和一个引用本地范围变量 foo 的方法。我重构了部分方法,不小心留下了对 foo 的引用;该变量不再在作用域中定义。它最终指向@foo。更改 foo 会更改 @foo,反之亦然。
简化版: 编辑:添加 ImOutOfNames。
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
bar_method_1 和 bar_method_2 的输出是“那是一个美味的汉堡”。我预计会出现错误,例如运行上面的代码会导致
NameError: undefined local variable or method
我什至让一位更高级的开发人员来看一看,他有些困惑并确认了这种行为。
这是预期的行为,我误解了 @variables 的工作原理还是有什么问题?
I came across an odd bug in my code that revealed an interesting behavior of ruby. Hopefully someone can explain why it behaves this way.
I had a class with an instance variable @foo and a method that referenced a locally scoped variable foo. I refactored part of the method out accidentally leaving the reference to foo; the variable no longer defined in the scope. It ended up pointing to @foo instead. Changing foo made changes to @foo and vice versa.
Simplified version:
EDIT : added ImOutOfNames.
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
And the output of bar_method_1 and bar_method_2 was "that is a tasty burger". I was expecting there to be an error, for example running the above code gets
NameError: undefined local variable or method
I even had a more senior developer come take a look and he was somewhat baffled and confirmed the behavior.
Is this an expected behavior and I misunderstood how @variables work or is there something wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您之前的错误代码可能位于 attr_accessor 定义中,该定义创建了一个访问您的实例变量的方法 foo,
如下所示,您可以具有相同的行为:
如果您的代码 call 在您的对象中定义了两个方法;
因此,在您的情况下,当没有定义局部变量时,会使用该方法,但由于您在此示例中没有调用 attr_accessor,所以您发布的方法未定义,并且没有可以在 bar_method_2 上使用的局部变量> 所以调用失败。
Your previous buggy code probably at an attr_accessor definition that created a method foo that accessed to your instance variable,
You can have the same behavior if your code is like this:
The attr_accessor call defines two methods in your object;
So in your case, when no local variable was defined, the method was used, but as you did not call attr_accessor in this example you posted the method was not defined and there was no local variable to use on bar_method_2 so the call fails.
您的 @foo 实例变量有 attr 访问器吗?这是发生这种情况的一种方式。
一般来说,我建议不要对本地范围的变量使用相同的名称,但是您可以找出它是否来自某种方法,
或者甚至是
使用 ruby 运行时定义的,这绝对会减少神秘感和神奇的本质一些代码。
Do you have an attr accessor for your @foo instance variable? That's one way this could happen.
I'd recommend not using the same name for a locally scoped variable, in general, but you can find out if it's coming from some method with
or if it's even defined with
Using the ruby runtime to your advantage definitely reduces the mysticism and magical nature of some code.