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."