如何在通过define_method创建方法时找到定义的方法

时间:2015-09-01 18:01:57

标签: ruby-on-rails ruby ruby-on-rails-4

有些模块正在为我的课程添加方法,可能是通过元编程:

class MyClass
  include SomeMetaProgrammedModule
  include SomeMetaProgrammedModule1
  include SomeMetaProgrammedModule2
  include SomeMetaProgrammedModule3
end

我想找到定义名为mysterious的方法的位置。我不能只是def mysteriousalias :mysterious,因为mysterious是使用

定义的
  def self.included(klass)
    klass.send(:define_method,"#{maybe_some_interpolation.gsub(...)}"
  end

如何找到定义的位置?如何追踪其来源?

2 个答案:

答案 0 :(得分:1)

您可以使用UnboundMethod类检查方法的定义。

调用Class的

.instance_method初始化一个新的UnboundMethod实例。

要查找定义mysterious的位置,您可以使用:

  MyClass.instance_method(:mysterious).source_location

返回:

["/Users/filip/crazy_project/SomeMetaProgrammingModule.rb", 21]

其中" 21"是行数

答案 1 :(得分:1)

如果我理解正确,您可以使用Module#instance_methodMethod#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 

编辑:我可能误解了“定义的位置”的含义。使用菲利普的答案,我获得:

C.instance_method(:kitten).source_location
  #=> ["t.rb", 3]