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 # => # 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变量的getter和setter的类游戏
  2. 默认情况下,@ in_progress为false
  3. 我们打电话开始! 方法并尝试将in_progress更改为true
  4. in_progress的Getter效果很好
  5. Setter只适用于自己。 或通过@in_progress直接访问变量

我在Ruby中阅读了关于方法查找的内容(向右移动一步到接收器的类中,然后向上移动祖先链,直到找到方法。)但我真的不知道为什么我必须使用self.in_progress = true访问setter方法。 特别是当getter方法无需自我时。

提前致谢!

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

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

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

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

尝试使用in_progress = 'hello' ,然后执行puts in_progress 。 您将意识到Ruby将使用局部变量in_progress