the12 the12 - 1 month ago 6
Ruby Question

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 Used: Windows 10.

I am using IRB and playing around with some of the getter/setter methods. If I delete the setter method
roar=(v)
, the reader method still works and will print out "GRRRxxz". However, if I quit IRB and launch another session, IRB will give me an error. Note that I am loading the files each time using the load keyword i.e.:
load "test.rb"
.

What's even more unusual is that if I update the
puts
after deleting the setter method, it will update the
puts
to whatever (i.e.: set GRRRxxz to YOOO, it will change to YOOO).

Can someone explain to me why IRB is operating in this manner? It seems to be saving the setter method for some inexplicable reason. It also does the same thing if you delete the reader method (will still work if you delete writer method, but an exiting and rebooting of IRB makes it fail).

Any help would be greatly appreciated!

Answer

IRB has nothing to do with this. It's a feature of ruby called "open classes"

So when you first load your Carnivore class, it is loaded in its entirety, because it didn't exist before. But if you then remove a method in a file and reload it, what happens is ruby opens your class and adds a getter method. Which it already had, so it's overwritten. Which explains why changes to method bodies (your puts there) are reflected.

This technique is what powers so-called "monkey-patching". You can patch any class in ruby, even a system one.

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

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

You see, it "patches" an existing class. If this class definition replaced/shadowed the one from the system, your app would be pretty broken.

Comments