Read more

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

Arne Hartherz
September 07, 2012Software engineer at makandra GmbH

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
Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

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.

Posted by Arne Hartherz to makandra dev (2012-09-07 10:27)