Not only must the spice flow... but the flow must also spice!

September 13, 2009

Creating irb and ruby-debug initializer files (.irbrc and .rdebugrc) in Windows

This isn't exactly a new topic, but I wanted to document how to setup both .irbrc and .rdebugrc at the same time. Basically these files are simple initialization scripts for irb (and thus the Rails console) and ruby-debug (the de facto debugging tool for Rails). The challenge here is that neither the irb nor the ruby-debug windows bindings specify where these files should be located. But they will reference the environment variables IRBRC and RDEBUGRC respectively, which can specify a file location!



First, so that we're on the same page, make sure that your version of Windows properly uses the %HOMEPATH% environment variable. The rest of this article is dependent upon it. Windows Vista uses this environment variable by default to point to \Users\<Username>\. To check, open up a command prompt and enter: echo %HOMEPATH% and you should get back your home path.


If instead you see just the string %HOMEPATH% echoed back to you then you'll need to set up an environment variable with this name that points to your home path. Or you can just use the full path anywhere I mention %HOMEPATH% below. In Vista the full path is C:\Users\<Username>\ or in XP it is C:\Documents and Settings\<Username>\.

If you're not sure how to add environment variables refer to this article.

Now that that's cleared up, let's get started.

1) Create the IRBRC and RDEBUGRC environment variables as in:


2) Create the files themselves in your %HOMEPATH% directory.

2a) In order to create the .irbrc file you will need to use your favorite text editor's Save As... function since Windows Explorer will not let you create a file that is all extension and no name (it sees ".irbrc" as being a no-name file with an extension of "irbrc"). So just open up E Text Editor or Notepad or your favorite text editor and save a new document as .irbrc within your %HOMEPATH% directory.


2b) Use the same process to create the rdebug.ini file. What's that? Yes I do mean rdebug.ini. Even though our RDEBUGRC environment variable points to a file called _rdebugrc the actual file should be called rdebug.ini! Otherwise, the file is not found and therefore not loaded up when the ruby-debug debugger starts. And honestly, I don't know why... but this setup is just what worked for me. Go figure!

OK. Now, as for what goes into these init files... well that's up to you! But the following is what I have.

Note: some of the requires in the below example .irbrc file will require corresponding gem installations.
  1. require 'map_by_method' => Install this gem with gem install map_by_method. Here's an article on map_by_method (also by Dr Nik).
  2. require 'what_methods' => Install this gem with gem install what_methods. There's not really a definitive source on what_methods that I can see, but basically what_methods is a way to see which methods, when performed on an object, return a particular value. For example:



Inside of .irbrc: (based on this article by Dr Nik)

require 'rubygems'
require 'irb/completion'
require 'map_by_method'
require 'what_methods'
require 'pp'

IRB.conf[:AUTO_INDENT] = true


####################################################################
# From http://blog.nicksieger.com/articles/2006/04/23/tweaking-irb
####################################################################
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]

module Readline
  module History
    LOG = "#{ENV['HOMEPATH']}/.irb-history"

    def self.write_log(line)
      File.open(LOG, 'ab') {|f| f << "#{line}\n"}
    end

    def self.start_session_log
      write_log("\n# session start: #{Time.now}\n\n")
      at_exit { write_log("\n# session stop: #{Time.now}\n") }
    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

# Remember irb command history across sessions
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOMEPATH']}/.irb-save-history"
####################################################################

# Clear screen
def cls
  system('cls')
end

# Return a list of methods defined locally for a particular object.  Useful
# for seeing what it does whilst losing all the guff that's implemented by its parents (eg Object).
class Object
  def local_methods(obj = self)
    (obj.methods - obj.class.superclass.instance_methods).sort
  end
end

# Call this method if you'd like to display all of ActiveRecord's generated
# SQL statements inside of your Console or ruby-debug session
def active_record_logging(stream = $stdout)
  ActiveRecord::Base.logger = Logger.new(stream)
  ActiveRecord::Base.connection_pool.clear_reloadable_connections!
end
####################################################################
# Hirb
####################################################################
# http://tagaholic.me/2009/03/13/hirb-irb-on-the-good-stuff.html
# http://tagaholic.me/hirb/doc/classes/Hirb.html
require 'hirb'
require 'yaml'
class Hirb::Helpers::Yaml
  def self.render(output, options={})
    output.to_yaml
  end
end
Hirb.enable({:width => 204, :height => 32}) # Specifies my console size
puts ".irbrc successfully loaded"


If your .irbrc file loads successfully you'll see the line ".irbrc successfully loaded" in your Rails console. If not then something isn't right! .irbrc failures will fail silently so try adding a puts statement higher up in the file to debug any problems. And again, make sure your HOMEPATH environment variable is working as the above script depends on it.

Want more? Check out this article for some pretty advanced initialization scripts.


Inside of rdebug.ini:

set autolist
set autoeval
set autoreload

If your rdebug.ini file loads successfully then you will automatically get a code listing in your Rails server console when breaking at a debugger point. As a ruby-debug quirk, I have found that autoreload doesn't always reload files automatically. So if your source code in the Rails server console ever looks out of date type in set autoreload again, at the debugger prompt. Just typing autoreload (without prepending "set") used to be enough, but as of ruby-debug v0.10.x will yield an error trace (I think this is probably a Windows binding artifact). But in any case, retyping the full set autoreload will do the trick when needed.

For instruction on using ruby-debug, check out this very thorough article, watch the railscasts screencast on ruby-debug, or just enter the help command at the prompt while debugging and play around. Or here's a quick reference that will get you most of the way:

l   => (short for "list") list the next frame of code
l=  => (short for "list" with "=" meaning current frame) list the current frame of code (this is the one I always use.)
n   => (short for "next") skip to next line
s   => (short for "step") step into next line
c   => (short for "continue") continue code execution normally. Future "debugger" statements will re-execute the debugger as normal.

Well that's it for now. Happy coding!

No comments:

Post a Comment