Ruby 为什么没有';是否定义了引用相同名称的实例变量?

Ruby 为什么没有';是否定义了引用相同名称的实例变量?,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

我在代码中遇到了一个奇怪的bug,它揭示了ruby的一个有趣行为。希望有人能解释它为什么会这样

我有一个带有实例变量@foo的类和一个引用局部范围变量foo的方法。我意外地重构了方法的一部分,留下了对foo的引用;变量不再在范围中定义。它最终指向@foo。更改foo会更改@foo,反之亦然

简化版: 编辑:添加iAutofNames

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