Use interactive_editor with irb for an inside-out Ruby IDE

An IDE is basically an editor with a built-in runtime and additional tools. With the interactive_editor, you can embed your favorite editor in Ruby's interactive runtime.

In programming parlance, REPL is a commonly bandied about term that means Read-Eval-Print Loop. It refers to an interactive programming language interpreter with an interface like a command shell. When you start up a REPL, you get a prompt, and you can issue commands that conform to the syntax of the REPL's language. For instance, the standard Ruby distribution comes with a REPL called irb:

> irb

irb(main):001:0> foo = 'Crule World' # Yes, that spelling is intentional.

=> "Crule World"

irb(main):002:0> def sendoff(target)

irb(main):003:1> puts "Goodbye, #{target}!"

irb(main):004:1> end

=> nil

irb(main):005:0> sendoff foo

Goodbye, Crule World!

=> nil

REPLs are useful for a fairly rapid development cycle, allowing developers to test code before committing it to the main project. A synergy of sorts develops when doing test-driven development, too; by writing your software such that it can be loaded as a library, you organize it in a manner that lends itself to unit testing, which means you organize it in a manner that allows you to load up the file in irb and execute pieces of it as discrete functions. Most REPLs offer simple facilities for loading up such a program and using the functions you write within the REPL itself to test how they work while you are writing them.

The separation between REPL and editor can be a bit annoying, though. Having to reload the code every time you make a change before you can test it adds a new step to the process that has to be taken many times in the course of a single session of development. Such repetitive, unchanging tasks, no matter how trivial when performed only once, become burdensome around the 50th time. These tasks are exactly the sorts of things we often wish to automate, to abstract away, when we sit down to write a program.

Wouldn't it be nice if we could open an editor from within the REPL itself, edit the code, and "save" it back to the REPL's environment? This would not only allow you to ease the process of working with files, but also provide a much more robust, flexible environment for entering code. Instead of entering every single line of code discretely without any ability to change your mind about the structure of a method apart from rewriting the whole thing from scratch, you could edit a method exactly as you would if writing code without the REPL, and still have it within a REPL to test execution at your whim.

There is a Ruby library called interactive_editor that provides this functionality. It is available through Ruby's gem tool, a software management system for Ruby libraries similar to Perl's CPAN tool:

gem install interactive_editor

You can also get it from its GitHub page. Its maintainer, Jan Berkel, based it on a tool created by Giles Bowkett and others in the middle of a public presentation. Berkel's version extends the basic concept slightly to add convenience features. It inherits the MIT/X11 license from Giles Bowkett's utility-belt project, which contains the code from which it was derived. This makes it copyfree software, which comes with some benefits.

Once the interactive_editor gem has been installed, setting it up is easy. First of all, if you are inclined to do so, you could check the source of the interactive_editor.rb file, under the Editors module near the end of the file, to see if any of the editors it supports by default are suitable to your needs. If not, you could add one simply and easily enough, but editing the file to do so is probably not the best way to do it. The relevant section of code, as of this writing, is:

:vi    => nil,

:vim => nil,

:emacs => nil,

:nano => nil,

:mate => 'mate -w',

:mvim => 'mvim -g -f' + case ENV['TERM_PROGRAM']

when ''; ' -c "au VimLeave * !open -a iTerm"'

when 'Apple_Terminal'; ' -c "au VimLeave * !open -a Terminal"'

else '' #don't do tricky things if we don't know the Term


Each of these Ruby symbols (e.g., :vi) corresponds to a method you can execute from within irb to start the relevant editor (e.g., vi).

The interactive_editor also supports one additional editor indicator -- "ed." This is not necessarily the basic ed available on Unix-like systems all over the world; it is a shortcut for the editor specified in your system's EDITOR environment variable. If that environment variable on your system refers to Vim, ed, xedit, or SciTE, interactive_editor will call that editor when you tell it to use "ed."

You can require interactive_editor from within an irb session and use that to start your editor of choice:

> irb

irb(main):001:0> require 'rubygems'

=> true

irb(main):002:0> require 'interactive_editor'

=> true

irb(main):003:0> vim

You can change that last line to specify a particular file, if you want to load a file you have already written into irb and edit it:

irb(main):003:0> vim 'xor.rb'

After making changes to the file, you can save and exit, and you will be returned to your irb session. All the methods defined in that file will then be available to you within the irb environment. In the case that you do not specify a particular file to open, the editor opens a temporary file containing the code currently defined in your irb REPL environment, allowing you to edit and save back to the environment.

Because you are unlikely to want to have to type those require statements every time you start irb, you should place them in the .irbrc file in your home directory (you may have to create the file from scratch). To use an editor other than the short list of six that are supported by default, there are several approaches you can take. In each case, you would use ed within irb to start the editor, rather than vim as shown in the above example.

The most obvious and comprehensive approach is probably to define the EDITOR environment variable for your shell. As an alternative, a temporary change to the EDITOR variable that applies only to irb can be set within either the irb session or the .irbrc file. In either case, just set the editor you wish to use like this (using xedit as the example editor):

ENV['EDITOR'] = 'xedit'

This is just a line in the file, for a "permanent" configuration setting in .irbrc. In irb, your session would include something like this:

irb(main):001:0> ENV['EDITOR'] = 'xedit'

=> "xedit"

Some editors may require special handling so that they will actually behave themselves; trying out various editors with interactive_editor in irb should give you an idea of which of them work gracefully with it and which do not.