Reputation: 5931
Some modules are adding methods to my class, probably via meta-programming:
class MyClass
include SomeMetaProgrammedModule
include SomeMetaProgrammedModule1
include SomeMetaProgrammedModule2
include SomeMetaProgrammedModule3
end
I want to find where a method named mysterious
is defined. I can't just grep def mysterious
or alias :mysterious
, because mysterious
is defined using
def self.included(klass)
klass.send(:define_method,"#{maybe_some_interpolation.gsub(...)}"
end
How do I find where it is defined? How do I track down its source?
Upvotes: 0
Views: 122
Reputation: 110675
If I understand the question correctly, you could use Module#instance_method and Method#owner:
module Cat
def self.included(klass)
klass.send(:define_method, :kitten) do
puts "mew"
end
end
def cat
puts "meow"
end
end
module Dog
define_method(:dog) { puts "woof" }
end
Dog.send(:define_method, :pup) { puts "wuf" }
class C
include Cat
include Dog
end
Cat.instance_methods #=> [:cat]
Dog.instance_methods #=> [:dog, :pup]
C.instance_methods(false) #=> [:kitten]
C.instance_methods & [:cat, :dog, :pup, :kitten] #=> [:kitten, :dog, :pup, :cat]
c = C.new
c.cat # "meow"
c.kitten # "mew"
c.dog # "woof"
c.pup # "wuf"
C.instance_method(:cat).owner #=> Cat
C.instance_method(:kitten).owner #=> C
C.instance_method(:dog).owner #=> Dog
C.instance_method(:pup).owner #=> Dog
Edit: I may have misunderstood what was meant by "where it is defined". Using Filip's answer, I obtain:
C.instance_method(:kitten).source_location
#=> ["t.rb", 3]
Upvotes: 1
Reputation: 5931
You can check where method is defined with the UnboundMethod
class.
.instance_method
called on Class initialises a new UnboundMethod
instance.
To find where mysterious
is defined you can use:
MyClass.instance_method(:mysterious).source_location
which returns:
["/Users/filip/crazy_project/SomeMetaProgrammingModule.rb", 21]
where "21" is the number of the line
Upvotes: 1