Module: MethodFinder

Defined in:
lib/methodfinder.rb,
lib/methodfinder/version.rb

Constant Summary collapse

ARGS =

Default arguments for methods :nodoc:

{
  cycle: [1], # prevent cycling forever
  tally: [],  # Since Ruby 3.1 Enumberable tally takes an optional hash
}.freeze
INSTANCE_METHOD_IGNORELIST =

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

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

Ignoring class methods

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

IGNORING classes

[]
VERSION =
'2.2.5'

Class Method Summary collapse

Class Method Details

.debug?Boolean

Checks whether or not debugging is currently enabled :doc:

Returns:

  • (Boolean)


69
70
71
# File 'lib/methodfinder.rb', line 69

def self.debug?
  @debug
end

.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#[]", ...]
MethodFinder.find("abc","ABC")
#=> ["String#swapcase", "String#swapcase!", "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", ...]


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/methodfinder.rb', line 91

def self.find(obj, res, *args, &block)
  find_methods(obj) do |met|
    o = begin
      obj.dup
    rescue StandardError
      obj
    end
    m = o.method(met)
    next unless m.arity <= args.size

    warn(met) if debug?
    a = ARGS.key?(met) ? ARGS[met] : args
    begin
      m.call(*a, &block) == res
    rescue StandardError
      nil
    end
  end
end

.find_classes_and_modulesObject

Returns all currently defined modules and classes.



112
113
114
115
116
117
118
119
120
# File 'lib/methodfinder.rb', line 112

def self.find_classes_and_modules
  with_redirected_streams do
    candidates = Object.constants - CLASS_IGNORELIST
    constants = candidates.sort.map { |c| Object.const_get(c) }
    constants.select do |c|
      c.instance_of?(Class) || c.instance_of?(Module)
    end
  end
end

.find_in_class_or_module(klass, 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]

:doc:



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/methodfinder.rb', line 138

def self.find_in_class_or_module(klass, pattern = /./)
  klasses = Object.const_get(klass.to_s)
  class_methods = begin
    klasses.methods(false)
  rescue StandardError
    []
  end
  instance_methods = klasses.instance_methods(false)
  all_methods = class_methods + instance_methods
  all_methods.grep(/#{pattern}/).sort
end

.find_unknown(obj, &block) ⇒ Object

Used by Object.find_method :nodoc:



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/methodfinder.rb', line 163

def self.find_unknown(obj, &block)
  find_methods(obj) do |met|
    warn(met) if debug?
    obj.class.class_eval("alias :unknown #{met}", __FILE__, __LINE__)
    subject = begin
      obj.dup
    rescue StandardError # dup doesn't work for immutable types
      obj
    end
    begin
      block.call(subject)
    rescue StandardError
      nil
    end
  end
end

.toggle_debug!Object

Toggles the debug mode



74
75
76
# File 'lib/methodfinder.rb', line 74

def self.toggle_debug!
  @debug = !@debug
end