我从this discussion得到了这个问题。类似object.m
的方法调用并不总是意味着“object”类具有“m”方法,就像Array对象的find方法不是直接源自Array对象,而是来自混合的Enumerable模块。我的问题是,给定一种方法,我们如何确定方法起源的类?
答案 0 :(得分:10)
任何类/对象方法都是Ruby中的一个对象,并且有一些自己的方法。
所以你可以这样做:
[].method(:count).inspect
=> "#<Method: Array#count>"
[].method(:detect).inspect
=> "#<Method: Array(Enumerable)#detect>"
RegEx的快点,你已经完成了。
答案 1 :(得分:7)
tobyhede的答案很棒,但我只是在irb
中进行了一些挖掘,并且没有必要将#inspect
的输出切片。 Method
类
>> Object.new.method(:inspect)
=> #<Method: Object(Kernel)#inspect>
有一些有用的方法:
>> Object.new.method(:inspect).methods - Object.methods
=> ["owner", "call", "to_proc", "unbind", "arity", "receiver", "[]"]
特别是#owner
方法,它将所有者作为正确的对象返回:
>> [].method(:count).owner
=> Array
>> [].method(:detect).owner
=> Enumerable
答案 2 :(得分:1)
也许你使用caller()给你回溯看看:
答案 3 :(得分:1)
我认为这样的事情可以发挥作用
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"
我想最后一个拥有该方法的人是定义它的人吗?
答案 4 :(得分:0)
我不确定我们是否可以精确地找到方法的来源,当你包含一个mixin时,所有方法都会成为你班级的一部分,就像你把它们放在那里一样。请参阅dylanfm的答案约。