Module: MethodFinder

Defined in:
lib/methodfinder.rb

Constant Summary collapse

ARGS =

Default arguments for methods

{
  cycle: [1] # prevent cycling forever
}
INSTANCE_METHOD_BLACKLIST =

Blacklisting methods, e.g. { :Object => [:ri, :vim] }

Hash.new { |h, k| h[k] = [] }
CLASS_METHOD_BLACKLIST =
Hash.new { |h, k| h[k] = [] }

Class Method Summary collapse

Class Method Details

.find(obj, res, *args, &block) ⇒ Object

Provided with a receiver, the desired result and possibly some arguments, MethodFinder.find will list all methods that produce the given result when called on the receiver with the provided arguments.

MethodFinder.find(10, 1, 3)
#=> ["Fixnum#%", "Fixnum#<=>", "Fixnum#>>", "Fixnum#[]", "Integer#gcd", "Fixnum#modulo", "Numeric#remainder"]
MethodFinder.find("abc","ABC")
#=> ["String#swapcase", "String#swapcase!", "String#upcase", "String#upcase!"]
MethodFinder.find(10, 100, 2)
#=> ["Fixnum#**"]
MethodFinder.find(['a','b','c'], ['A','B','C']) { |x| x.upcase }
#=> ["Array#collect", "Array#collect!", "Enumerable#collect_concat", "Enumerable#flat_map", "Array#map", "Array#map!"]


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/methodfinder.rb', line 70

def find(obj, res, *args, &block)
  redirect_streams

  mets = methods_to_try(obj).select do |met|
    o = obj.dup rescue obj
    m = o.method(met)
    if m.arity <= args.size
      a = args.empty? && ARGS.has_key?(met) ? ARGS[met] : args
      m.call(*a, &block) == res rescue nil
    end
  end
  mets.map { |m| "#{obj.method(m).owner}##{m}" }
ensure
  restore_streams
end

.find_classes_and_modulesObject

Returns all currently defined modules and classes.



87
88
89
90
# File 'lib/methodfinder.rb', line 87

def find_classes_and_modules
  constants = Object.constants.sort.map { |c| Object.const_get(c) }
  constants.select { |c| c.class == Class || c.class == Module}
end

.find_in_class_or_module(c, pattern = /./) ⇒ Object

Searches for a given name within a class. The first parameter can either be a class object, a symbol or a string whereas the optional second parameter can be a string or a regular expression:

MethodFinder.find_in_class_or_module('Array', 'shuff')
#=> [:shuffle, :shuffle!]
MethodFinder.find_in_class_or_module(Float, /^to/)
#=> [:to_f, :to_i, :to_int, :to_r, :to_s]

If the second parameter is omitted, all methods of the class or module will be returned.

MethodFinder.find_in_class_or_module(Math)
#=> [:acos, :acosh, :asin ... :tanh]


108
109
110
111
112
113
114
# File 'lib/methodfinder.rb', line 108

def find_in_class_or_module(c, pattern=/./)
  cs = Object.const_get(c.to_s)
  class_methods = cs.methods(false) rescue []
  instance_methods = cs.instance_methods(false)
  all_methods = class_methods + instance_methods
  all_methods.grep(/#{pattern}/).sort
end

.methods_to_try(obj) ⇒ Object

Returns a list of candidate methods for a given object. Added by Jan Lelis.



117
118
119
120
121
122
123
124
125
# File 'lib/methodfinder.rb', line 117

def methods_to_try(obj)
  ret = obj.methods
  blacklist = obj.is_a?(Module) ? CLASS_METHOD_BLACKLIST : INSTANCE_METHOD_BLACKLIST
  klass = obj.is_a?(Module) ? obj : obj.class

  klass.ancestors.each { |ancestor| ret -= blacklist[ancestor.to_s.intern] }

  ret.sort
end