【问题标题】:Ruby - instance methods: why can i use getter without self, but setter only with selfRuby - 实例方法:为什么我可以使用没有 self 的 getter,但只能使用 self 的 setter
【发布时间】:2013-11-06 04:26:10
【问题描述】:

我使用 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 变量使用 getter 和 setter 的类游戏
  2. @in_progress 默认为 false
  3. 我们叫开始!方法并尝试将 in_progress 更改为 true
  4. in_progress 的吸气剂效果很好
  5. Setter 仅适用于自身。或通过@in_progress 直接访问变量

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

提前致谢!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    当您执行in_progress = true 时,实际上是在您的方法中创建了一个局部变量,而不是访问您的设置器。

    当您执行 puts in_progress 时,Ruby 会检查 in_progress 局部变量,当找不到时,它会查找您的类的 getter。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢!这就是我所需要的。
      猜你喜欢
      • 1970-01-01
      • 2021-06-05
      • 2012-08-18
      • 1970-01-01
      • 2012-07-12
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多