pm: Print Methods

Ruby has a very convenient method to inspect objects: “p”. It just prints the result of “inspect”. And it’s exactly what irb uses to show the result of each expression.

Anyway, the cool guys at projectionist just posted a little method of theirs called “m”, which provides easy access to an object’s methods.

That made me remember my old (well, not that old) “pm” method for irb, which even if I haven’t talked about here, I’ve made public at dotfiles as part of my irbirc (it’s the last method).

Anyway, looking at their implementation, I decided to polish mine and release it here:

ANSI_RESET        = "33[0m"
ANSI_BOLD         = "33[1m"
ANSI_GRAY         = "33[1;30m"
ANSI_LGRAY        = "33[0;37m"

def pm(obj, *options) # Print methods
  methods = obj.methods - (options.include?(:more) ? [] : Object.methods)
  filter = options.select {|opt| opt.kind_of? Regexp}.first
  methods = methods.select {|name| name =~ filter} if filter

  data = methods.sort.collect do |name|
    method = obj.method(name)
    args = "(" + case method.arity <=> 0
    when 1
      (”a”..(?a + method.arity - 1).chr).to_a.join(”, “)
    when -1
      (”a”..(?a - method.arity - 1).chr).to_a.join(”, “)
    else
      “”
    end + “)”
    klass = $1 if method.inspect =~ /Method: (.*?)#/
    klass = $1 if klass =~ /((.*?))/
    [name, args, klass]
  end
  max_name_length = data.collect {|item| item[0].size}.max
  max_args_length = data.collect {|item| item[1].size}.max
  data.each do |item|
    print ” #{ANSI_BOLD}#{item[0].rjust(max_name_length)}#{ANSI_RESET}”
    print “#{ANSI_GRAY}#{item[1].ljust(max_args_length)}#{ANSI_RESET}”
    print ”   #{ANSI_LGRAY}#{item[2]}#{ANSI_RESET} n”
  end
  data.size
end

Don’t try to understand it unless you can understand it :-)… just copy it to your .irbrc (you do have an irbrc file, don’t you?). And use it like this:

pm "a"

pm "a", :more

pm "a", /regexp/

9 Responses to “pm: Print Methods”

  1. Stephan Says:

    Really nice, thanks.

    The line

    print ” #{ANSI_LGRAY}#{item[2]}#{ANSI_RESET}n”

    Should be

    print ” #{ANSI_LGRAY}#{item[2]}#{ANSI_RESET}\n”

    Note the backslash just before the last ‘n’.

  2. Dr Nic Says:

    Very nice. My gumby windows irb didn’t like the colours, but I can live with black and white. Unless someone can fix my colour issues :)

  3. Dr Nic Says:

    OT: the feed link in your header is: http://www.notsostupid.com/feed/, but it should be http://www.notsostupid.com/feed/rss/

  4. Rick Says:

    nice, but you could easily make it more object-oriented, e.g.:

    class Object; def pm(*options); methods = self.methods… …

  5. Ryan Davis Says:

    please turn off smarty or whatever is curling the quotes.

  6. Ryan Davis Says:

    and escaping all backslashes… like the one in the regex that now reads ((blah)) instead of \((blah)\)

  7. Giles Bowkett Says:

    This is awesome. I love it.

  8. Kevin Marsh Says:

    Beautiful! Can you share your Terminal.app color theme? Can’t seem to get it working like yours.

  9. topfunky Says:

    Copying the script off the dotfiles site works for me.

    Thanks, SD! Another nice addition to my .irbrc.

    http://dotfiles.org/~sd/.irbrc

Leave a Reply