Iterative development in irb

There are times when irb’s line-based interface is too constrained for experimentation with an algorithm or other piece of Ruby code. When that happens, I usually switch to a proper editor, edit the file, and run it. It works pretty well.

However, some environments (Rails especially) take a long time to start up, making this style of development time-consuming. It’s far better to start the environment once and run just the test code each time it’s changed.

You could switch to the console and type load 'myfile.rb' each time … or you could add this to your .irbrc:

def loop_execute(file)
  old_mtime = nil
  loop do
    # print("\e[sWaiting...")
    sleep(0.2) while (mtime = File.stat(file).mtime) == old_mtime
    # print("\e[u\e[K")
    begin
      r = eval(File.read(file))
      puts("=> #{r.inspect}")
    rescue IRB::Abort
      puts("Abort")
      return
    rescue Exception => e
      puts("#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}")
    end
    old_mtime = mtime
  end
end

This will check the file for changes five times a second, and evaluate it in the current context if it has changed. Like irb, it prints the last result to the console. It’s a trivial snippet of code, but I think it’s useful.

To use it, just type:

loop_execute('myfile.rb')

in irb. Control-C will return control to the regular irb shell.

If you want some notification that the process is waiting, uncomment the two print lines. (I’m fairly sure that those ANSI escape sequences won’t work on Windows, though.)