这是 How to determine the class a method was defined in? 的后续问题(希望您不要介意相似性)
给定一个类层次结构,方法可以检索自己的Method
实例吗?
class A
def foo
puts "A#foo: `I am #{method(__method__)}'"
end
end
class B < A
def foo
puts "B#foo: `I am #{method(__method__)}'"
super
end
end
A.new.foo
# A#foo: `I am #<Method: A#foo>'
B.new.foo
# B#foo: `I am #<Method: B#foo>'
# A#foo: `I am #<Method: B#foo>' # <- A#foo retrieves B#foo
这样B.new.foo
代替打印
# B#foo: `I am #<Method: B#foo>'
# A#foo: `I am #<Method: A#foo>' # <- this is what I want
在上一个问题中,Jörg W Mittag suspected检索定义方法的类可能会违反面向对象的范例。这也适用于此吗?
不应该是一种方法&#34;了解自己&#34;?
答案 0 :(得分:3)
我找到了method,确切地说就是这样。
class A
def foo
puts "A#foo: `I am #{method(__method__).super_method || method(__method__)}'"
end
end
我真的很佩服Matz和Ruby核心开发人员。这种方法的存在意味着他们考虑到了这种情况,并考虑过如何处理它。
答案 1 :(得分:2)
根据How to determine the class a method was defined in?的回答和@ sawa关于super_method
的回答,你可以使用:
def meth(m, clazz)
while (m && m.owner != clazz) do
m = m.super_method
end
return m
end
class A
def foo
puts "A#foo: `I am #{meth(method(__method__), Module.nesting.first)}'"
end
end
class B < A
def foo
puts "B#foo: `I am #{meth(method(__method__), Module.nesting.first)}'"
super
end
end
B.new.foo
# B#foo: `I am #<Method: B#foo>'
# A#foo: `I am #<Method: A#foo>'
这里的想法是,因为我们知道方法由Module.nesting.first
定义的类/模块,所以我们采用method(__method__)
找到的当前方法对象并遍历其super
链到找到其所有者与定义方法的类/模块相同的方法实例。