Tweaking IRB
Posted by Nick Sieger Sun, 23 Apr 2006 04:02:00 GMT
IRB (Interactive Ruby Shell) is one of those tools that a hacker learning Ruby hopefully discovers right away. It’s an extremely useful way to learn the language, verify hunches, test assumptions, and get immediate feedback. IRB promotes learning by doing, which is the best way of making something stick in your head. (You can even try an online version of irb without even installing Ruby!)
The first order of business when using IRB is to setup your
preferences. If you haven’t done so already, create the file
~/.irbrc
(%USERPROFILE%.irbrc
on windows native ruby). .irbrc
is just a regular ruby script where you can run arbitrary ruby code at
the start of your IRB session. Add the following to .irbrc
:
require 'irb/completion'
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
This sets up usage of readline in your session and turns on TAB
completion, making IRB feel as comfortable as regular old bash
. Now
you can type Kernel::<TAB>
and get a list of available methods!
Good.
Next, the thing that you find yourself doing after using IRB for a
while is cutting and pasting code from your console buffer over to
your text editor. Don’t have Ruby’s reflection rules down yet? Not
sure whether to use instance_eval
or module_eval
when working on
that metaprogramming hack? Working inside Rails’ script/console
and
searching for the right ActiveRecord finder options? No matter how
good your terminal program, you probably have to use the mouse to
select text out of it to copy to your text editor, and hackers hate
having to switch from the keyboard to the mouse when in the flow of
programming.
So here’s a technique that will append commands entered in your IRB
session to a file in your home directory (idea from
ruby-talk:58931). Put the following in your .irbrc
:
module Readline
module History
LOG = "#{ENV['HOME']}/.irb-history"
def self.write_log(line)
File.open(LOG, 'ab') {|f| f << "#{line}
"}
end
def self.start_session_log
write_log("
# session start: #{Time.now}
")
at_exit { write_log("
# session stop: #{Time.now}
") }
end
end
alias :old_readline :readline
def readline(*args)
ln = old_readline(*args)
begin
History.write_log(ln)
rescue
end
ln
end
end
Readline::History.start_session_log
Now every line typed into IRB will immediately be saved into
~/.irb-history
. Exercise left to the reader to bind a custom
keystroke and macro to yank the last line out of that file and
automatically paste into your text editor.
Long-time bash
users know that the shell maintains a history of
commands across sessions so that you can access commands you typed
yesterday. Wouldn’t it be nice to do this in IRB as well? Wish
granted:
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
Happy ruby hacking! If you find any more handy IRB tips leave them at rubygarden, and let me know about them.
Footnote: I realize there is duplication and non-DRY happening here with two copies of your IRB history, but I came across these techniques at two different times, and the functions they serve seem different enough to potentially use them both. If you don’t like that, choose whichever is more appropriate for your needs.
(Hope this post serves your needs Dan.)