Ruby 如何确定指定方法的源类?

Ruby 如何确定指定方法的源类?,ruby,Ruby,我是从你那里得到这个问题的。像object.m这样的方法调用并不总是意味着“object”类有一个“m”方法,就像数组对象的find方法不是直接来自数组对象,而是来自混合的可枚举模块。我的问题是,给定一个方法,我们如何确定该方法起源于哪个类?也许您可以使用caller()提供回溯跟踪,请参见: 我在想这样的办法可能行得通 def print_ancestor_definitions(cl,method) ancestors = cl.ancestors p ancestors.join(

我是从你那里得到这个问题的。像
object.m
这样的方法调用并不总是意味着“object”类有一个“m”方法,就像数组对象的find方法不是直接来自数组对象,而是来自混合的可枚举模块。我的问题是,给定一个方法,我们如何确定该方法起源于哪个类?

也许您可以使用caller()提供回溯跟踪,请参见:


我在想这样的办法可能行得通

def print_ancestor_definitions(cl,method)
  ancestors = cl.ancestors
  p ancestors.join(' < ') #Print heirarchy
  p "Searching..."
  ancestors.each do |c|
    if c.instance_methods.include? method
      p "#{c} defines #{method} as an instance method!"
    elsif c.singleton_methods.include? method
      p "#{c} defines #{method} as a singleton method"
    else
      p "#{c} doesn't define #{method}"
    end
  end
end

print_ancestor_definitions(Array,'find')
# >> "Array < Enumerable < Object < Kernel"
# >> "Searching..."
# >> "Array defines find as an instance method!"
# >> "Enumerable defines find as an instance method!"
# >> "Object doesn't define find"
# >> "Kernel doesn't define find"
def打印祖先定义(cl,方法)
祖先
p祖先。加入(“<”)#列印继承权
p“搜索…”
每个人都有|
如果c.instance\u methods.include?方法
p“#{c}将#{method}定义为实例方法!”
elsif c.singleton_方法包括?方法
p“#{c}将#{method}定义为单例方法”
其他的
p“#{c}不定义#{method}”
结束
结束
结束
打印祖先定义(数组,'find')
#>>“数组<可枚举<对象<内核”
#>>“正在搜索…”
#>>“数组将find定义为实例方法!”
#>>“Enumerable将find定义为实例方法!”
#>>“对象未定义查找”
#>>“内核未定义查找”

我想最后一个拥有这个方法的人是定义它的人?

我不确定我们是否能准确地找到一个方法的来源,当你包含一个mixin时,所有的方法都会成为你的类的一部分,就像你把它们放在那里一样。请参阅dylanfm的答案,了解一个大概的答案。

任何类/对象方法都是Ruby中的对象,并且有自己的一些方法

所以你可以这样做:

[].method(:count).inspect
=> "#<Method: Array#count>"

[].method(:detect).inspect
=> "#<Method: Array(Enumerable)#detect>"
[]方法(:计数)。检查
=> "#"
[]方法(:检测)。检查
=> "#"

快一点正则表达式,你就完成了

tobyhede的答案非常棒,但我只是在
irb
中做了一些挖掘,没有必要对
#inspect
的输出进行切片。
方法

>> Object.new.method(:inspect)
=> #<Method: Object(Kernel)#inspect>
特别是
#owner
方法,它将所有者作为适当的对象返回:

>> [].method(:count).owner
=> Array
>> [].method(:detect).owner
=> Enumerable

method.inspect将告诉您,如果一个方法附加到一个Mixinawesome find,这肯定会派上用场。
>> [].method(:count).owner
=> Array
>> [].method(:detect).owner
=> Enumerable