PRY or IRB - reload class and forget deleted functionality
Asked Answered
D

3

5

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!

Deathbed answered 22/11, 2014 at 3:5 Comment(0)
H
6

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)
Haplite answered 22/11, 2014 at 6:54 Comment(0)
I
3

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

reload!
Ichnography answered 19/10, 2018 at 9:30 Comment(1)
This is rails only, afaik!Macroclimate
D
2

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.

Derrik answered 22/11, 2014 at 7:37 Comment(5)
It seems to open another Ruby (+ some libraries). That costs you another ~80 Mb ram. It may be a bug in the older/windows version but anyone trying this should be aware of that.Anthropomorphism
Which does open another Ruby and some libraries? The pry reset or the exec($0)? Anyone trying what should be aware of that too, @DarekNędza :)Derrik
Oh, right. I forgot about the most important thing. Well, I have checked both, the Pry and the IRB, and they both open another ruby.exe. Additional info for curious people: reset is exec 'pry' (+ some Pry's things). $0 in the IRB seems to be "irb" and in the pry, $0 it is "pry".Anthropomorphism
I did not mean the exec($0) in pry, as that is not what the command is to reset pry, but a reset command itself. Although, internally, it may indeed use exec($0). So did you mean that in both cases the memory increases when you do the appropriate way to reset? Or do you mean to say that if I load the application in itself, it will increase by that amount of memory?Derrik
Yes, when I enter exec($0) or reset the memory increase.Anthropomorphism

© 2022 - 2024 — McMap. All rights reserved.