Ruby - 实例方法:为什么我可以在没有 self 的情况下使用 getter,而只能使用 self 的 setter



我已经使用Ruby一段时间了。现在,我将深入挖掘并找到我所遇到的问题的所有答案。我希望我能在这里找到答案。所以这是我在下面的代码中的问题:

class Game
  attr_accessor :in_progress
  def initialize
    @in_progress = false
  end
  def start!
    # debug info                                                                         
    puts self.inspect                        # => #<Game:0x8f616f4 @in_progress=false>
    puts self.class.instance_methods(false)  # => [:in_progress, :in_progress=, :start!]
    puts self.instance_variables             # => [:@in_progress]
    puts self.respond_to?("in_progress=")    # => true
    puts in_progress      # => true - getter works without self
    # main quesion
    in_progress = true    # Why setter doesn't work without self?
    # self.in_progress = true   # this would work and set @in_progress to true becase setter called
    # @in_progress = true       # this would work as well because we set instance variable to true directly
  end
end
g = Game.new
g.start!
puts g.in_progress # => false - setter in start! method didn't work

我们在这里有什么:

  1. 具有@in_progress变量的吸气器和二传手的类游戏
  2. 默认情况下@in_progress为假
  3. 我们调用 start! 方法并尝试将in_progress更改为 true
  4. 吸气剂in_progress效果很好
  5. Setter 只与 self 一起工作,或者通过 @in_progress 直接访问变量

我读到了 Ruby 中的方法查找(向右走一步进入接收器的类,然后沿着祖先链向上,直到找到方法。但我真的不知道为什么我必须使用 self.in_progress=true 才能访问 setter 方法。特别是当吸气方法在没有自我的情况下工作时。

提前感谢!

因为您正在为函数中的局部变量in_progress赋值,而不是实例变量。getter 之所以有效,是因为 Ruby 会查询 start! 函数的本地命名空间以获取in_progress,它找不到它,然后它会查询实例命名空间,它会找到一个名为 in_progress 的方法并调用它。

Ruby 解释器无法确定您是要在局部in_progress还是在实例变量上分配 true 值,因此规则是在本地分配它(到 start! 中的当前命名空间)。

当你做in_progress = true时,你实际上在你的方法中创建了一个局部变量,而不是访问你的setter。

当你做puts in_progress时,Ruby 会检查一个in_progress局部变量,当它找不到它时,它会去找你类的 getter。

尝试做in_progress = 'hello',然后做puts in_progress。你会意识到Ruby将使用局部变量in_progress

相关内容

最新更新