Ruby 是否将某些文件保存在 IRB 中,因此 "load" 不会每次都加载文件的单独版本?

Does Ruby save certain files in IRB so "load" does not load a separate version of the file everytime?

class Carnivore
  def roar=(v)
    @roar = v
  end

  def roar
    @roar
  end
end

  trex = Carnivore.new
  trex.roar = "GRRRxxz"
  puts trex.roar

OS 使用:Windows 10.

我正在使用 IRB 并使用一些 getter/setter 方法。如果我删除 setter 方法 roar=(v),reader 方法仍然有效并会打印出 "GRRRxxz"。但是,如果我退出 IRB 并启动另一个会话,IRB 会给我一个错误。请注意,我每次都使用加载关键字加载文件,即:load "test.rb"

更不寻常的是,如果我在删除 setter 方法后更新 puts,它会将 puts 更新为任何内容(即:将 GRRRxxz 设置为 YOOO,它将更改为 YOOO)。

有人可以向我解释为什么 IRB 以这种方式运作吗?它似乎出于某种莫名其妙的原因正在保存 setter 方法。如果你删除 reader 方法,它也会做同样的事情(如果你删除 writer 方法仍然有效,但 IRB 的退出和重新启动会使它失败)。

如有任何帮助,我们将不胜感激!

IRB 与此无关。这是 ruby 的一项功能,称为 "open classes"

因此,当您第一次加载 Carnivore class 时,它会被完整加载,因为它之前不存在。但是,如果您随后删除文件中的一个方法并重新加载它,会发生 ruby 打开 您的 class 并添加一个 getter 方法。它已经有了,所以它被覆盖了。这解释了为什么对方法体的更改(你的 puts 在那里)被反映出来。

这项技术就是所谓的 "monkey-patching"。您可以修补 ruby 中的任何 class,甚至是系统修补程序。

class String
  def pirate
    self + ', arrrr!'
  end
end

'hello'.pirate # => "hello, arrrr!"

你看,它 "patches" 一个现有的 class。如果这个 class 定义 replaced/shadowed 来自系统,你的应用程序会很糟糕。