Hack of the day: Find all classes that define a method with a given name

If (for some reason that you don't want to ask yourself) you need to know all classes that define a method with a given name, you can do it like this:

def classes_defining_method(method_name)
  method_name = method_name.to_sym
  ObjectSpace.each_object(Module).select do |mod|
    instance_methods = mod.instance_methods.map(&:to_sym) # strings in old Rubies, symbols in new Rubies
    (instance_methods & [method_name]).any? && mod.instance_method(method_name).owner == mod
  end
end

So, when we want to know all classes that define a to_s on a plain IRB, this is what the result looks like:

>> classes_defining_method(:to_s)
=> [IRB::Context, UnboundMethod, Method, Proc, Process::Status, Time, Range, MatchData, Regexp, Struct, Hash, Array, Bignum, Float, Fixnum, NameError, Exception, String, FalseClass, TrueClass, Symbol, NilClass, Kernel, Module] 

All those classes implement their own to_s, note how we don't see any subclasses that inherit to_s from a parent. This is what our second condition in the code above does.

You can now go ahead and monkey-patch the hell out of all those classes implementing the method you are looking for.

Arne Hartherz Over 11 years ago