From: grady@... (Steven Grady) Date: 2002-01-31T07:04:36+09:00 Subject: MethodFinder For your amusement (and perhaps edification and/or utility), here is some code to find methods which when invoked on specified objects, provide a given result. This is inspired by the Squeak MethodFinder class. This is much simpler in various ways. I just whipped this together, so I'm sure there are possible improvements. #!/usr/local/bin/ruby class Array def permutations if size < 2 return [self] end perm = [] each {|e| (self - [e]).permutations.each {|p| perm << ([e] + p) } } perm end end $DummyOut = Object.new class << $DummyOut def write(aString) end end def methodFinder(operands, result) methodsFound = [] # Avoid producing default output, e.g. for String#display saveOut = $> $> = $DummyOut operands.each {|obj| obj.methods.each {|m| (operands-[obj]).permutations.each {|args| meth = obj.dup.method(m) if meth.arity == args.length or meth.arity < 0 then begin if meth.call(*args) == result then pretty = nil if m !~ /\w/ then pretty = "#{obj.inspect} #{m} #{args}" elsif meth.arity == 0 then pretty = "#{obj.inspect}.#{m}" else pretty = "#{obj.inspect}.#{m}(#{args.join(',')})" end methodsFound << pretty end rescue Exception end end } } } $> = saveOut methodsFound end puts methodFinder(['foo'], 'oof').join(', ') # -> "foo".reverse!, "foo".reverse puts methodFinder([2, 4], false).join(', ') # -> 2 > 4, 2 == 4, 2 >= 4, 2 === 4, 2.eql?(4), 2.equal?(4), 2 =~ 4, 4 < 2, 4 == 2, 4 <= 2, 4 === 2, 4.eql?(2), 4.equal?(2), 4 =~ 2 puts methodFinder([1.5, 1], 2).join(', ') # -> 1 << 1.5 puts methodFinder(["hello", 0..0], "h").join(', ') # -> "hello".slice(0..0), "hello" [] 0..0, "hello".slice!(0..0) -- Steven "In accordance with our principles of free enterprise and healthy competition, I'm going to ask you two to fight to the death for it."