PRY or IRB - reload class and forget deleted functionality

3.5k views Asked by At

If you change a file then re-load it in pry or irb, it seems to pick up any NEW functionality you've added to that class, but doesn't forget about OLD functionality you've deleted from that class.

Steps to reproduce:

  1. Create a class with a single method - eg. say_hello.
  2. Open PRY or IRB, and load 'my_class.rb'
  3. Edit your class - delete the existing method, and add a new one with a different name - eg. say_goodbye
  4. reload your class - load 'my_class.rb'

BOTH your methods will now be available. I see why this happens - because ruby allows you to re-open classes for modification, re-loading your file basically just re-opens the existing version of the class you'd already loaded, rather than wiping the memory of that class and defining the class again from scratch.

My question is, how do you work around this, apart from quitting and re-starting PRY or IRB? How do you just say "forget my previous class completely and re-load this file from scratch"?

Thanks!

3

There are 3 answers

0
Uri Agassi On BEST ANSWER

You can use remove_const to remove the class from its parent, either from the Module it is in:

My::Module.send(:remove_const, :MyClass)

or from Object if it was not declared inside a Module:

Object.send(:remove_const, :MyClass)
5
vgoff On

While you are in pry, you can use reset and that will reset the environment.

To reset IRB you can see this answer which is to say exec($0)

According to reset is exec 'pry' (+ some Pry's things). $0 in the IRB seems to be "irb" and in the pry, $0 it is "pry".

$0 is a global variable that means 'the running program' and so that is not surprising.

Look at the source code in Pry for the reset command though, I am somewhat surprised that they refer to pry by name, rather than this well known variable.

Here is the code from Pry that gives the functionality of reset, and why it increases memory use.

class Command::Reset < Pry::ClassCommand
  match 'reset'
  group 'Context'
  description 'Reset the REPL to a clean state.'

  banner <<-'BANNER'
    Reset the REPL to a clean state.
  BANNER

  def process
    output.puts 'Pry reset.'
    exec 'pry'
  end
end

The third line from the last in this listing being the one.

The cleaner way is actually doing the housekeeping yourself, as answered by Uri.

1
VxJasonxV On

If you don't need to selectively reload specific modules, classes, etc., and want to preserve your local variables, just:

reload!