Here’s a tool that I didn’t know I couldn’t do without - Andrew Birkett version of Smalltalk’s MethodFinder. Fabulous stuff.

I needed to record the source code for later…

class Object
  # Clone fails on numbers, but they're immutable anyway
  def megaClone
    begin self.clone; rescue; self; end
  end
end

class MethodFinder

  # Find all methods on [anObject] which,
  # when called with [args] return [expectedResult]
  def self.find(anObject, expectedResult, *args )
    anObject.methods.select { |name| anObject.method(name).arity == args.size }.
      select { |name| begin anObject.megaClone.method( name ).call(*args) ==
        expectedResult;  rescue; end }
  end

  # Pretty-prints the results of the previous method
  def self.show( anObject, expectedResult, *args )
    find( anObject, expectedResult, *args ).each { |name|
      print "#{anObject.inspect}.#{name}"
      print "(" + args.map { |o| o.inspect }.join(", ") + ")" unless args.empty?
      puts " == #{expectedResult.inspect}"
    }
  end
end

UPDATE: Syntax in why’s version of MethodFinder is even more intuitive. Going along with his recommendation I also need to add this to my ~/.irbrc.

UPDATE #2: RedHanded users added a bunch of tweaks that ended up in this .irbrc file