2012-07-13 56 views
10

這裏假設是一些任意的代碼庫,我不知道:我可以檢測到方法已被覆蓋嗎?

class Foo 
    def hi 
    end 
end 

class Bar < Foo 
    def hi 
    end 
end 

再假設我有一些代碼在那裏我通過Bar作爲參數。

def check(x) 
    do_something_with(x.method(:hi)) 
end 

在上述例子中,我可以知道x.hi(其中x引用Bar一個實例)不同於Foo#hi


基於加雷思的答案,這是我到目前爲止有:

def is_overridden?(method) 
    name = method.name.to_sym 
    return false if !method.owner.superclass.method_defined?(name) 
    method.owner != method.owner.superclass.instance_method(name).owner 
end 

醜惡?華麗?

+0

雖然它不一定相關,但我很好奇你爲什麼要這樣做。 – 2012-07-13 03:03:58

+0

另外,它似乎只關心繼承方面的「重寫」,而不是在同一個類上重新定義現有方法? – 2012-07-13 03:07:17

回答

9

你可以這樣做:

if x.method(:hi).owner == Foo 

我遠遠不是一個Ruby專家;如果有人比這更好的方式,我不會感到驚訝。

+0

不錯!我自己也偶然發現了同樣的事情。和你一樣 - 我會等待看看是否有其他人出現,併爲此採取行動。如果沒有,我會接受這個,因爲我認爲我可以用它來實現我所追求的目標。 – 2012-07-13 00:13:16

+0

@DanTao在你的情況下可能無關緊要,但如果Foo是猴子補丁,它仍然會報告Foo是所有者。 – 2012-07-13 00:15:45

+0

我真的不知道它在這種情況下如何做其他事情。 (無論如何,猴子補丁不會覆蓋*)我錯過了什麼? – 2012-07-13 00:17:22

0

有趣的問題!我想知道同樣的問題。您可以重新打開Bar類並檢查Bar的查找路徑中的祖先是否具有已定義的方法。

class Bar < Foo 
    ancestors.each do |ancestor| 
    puts ancestor if ancestor.instance_methods.include?(:hi) 
    end 
end 
相關問題