为什么尚未定义的局部作用域变量会引用同名的实例变量?

发布于 2024-11-29 22:36:21 字数 780 浏览 2 评论 0原文

我在代码中发现了一个奇怪的错误,它揭示了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感性不性感 2024-12-06 22:36:21

您之前的错误代码可能位于 attr_accessor 定义中,该定义创建了一个访问您的实例变量的方法 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

如果您的代码 call 在您的对象中定义了两个方法;

def foo
  @foo
end

def foo=(value)
  @foo = value
end

因此,在您的情况下,当没有定义局部变量时,会使用该方法,但由于您在此示例中没有调用 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:

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

The attr_accessor call defines two methods in your object;

def foo
  @foo
end

def foo=(value)
  @foo = value
end

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.

北方的巷 2024-12-06 22:36:21

您的 @foo 实例变量有 attr 访问器吗?这是发生这种情况的一种方式。

一般来说,我建议不要对本地范围的变量使用相同的名称,但是您可以找出它是否来自某种方法,

self.method(:foo)

或者甚至是

defined? foo

使用 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

self.method(:foo)

or if it's even defined with

defined? foo

Using the ruby runtime to your advantage definitely reduces the mysticism and magical nature of some code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文