2009-11-08 1 views
6

言う、Iしている以下の2つのクラスをオーバーライドしていなかったことを検出しますしたがって、Bではオーバーライドされませんか?方法は

アップデート:私は「受け入れられた」として、チャックの答えをマークしたが解決

は、後でパオロPerrotaは私が解決策を明らかにシンプルにできることを実感しました、そしてそれはおそらく、以前のバージョンで動作しますルビーも。常に次のことができます

B.singleton_methods(false).include?("a_class_method") 

答えて

7

Ruby 1.8.7以上を使用している場合は、 Method#owner/UnboundMethod#ownerで簡単です。

class Module 
    def implements_instance_method(method_name) 
    instance_method(method_name).owner == self 
    rescue NameError 
    false 
    end 
end 
+0

ありがとう!特に最初に言及したRubyのバージョンが1.9から1.8.7(実際に使用しています)になったのを見てうれしく思います。 – mxgrn

+0

ええ、私はちょっとぼんやりしていました。最初は1.8.7で動作していると思っていましたが、 'Method#owner'が1.8.7 riドキュメントにないことを知ったので、それを1.9に変更してから、1.8.7とsawでメソッドが存在するかどうかを実際に確認しました私が最初に正しいことをしたこと。喜んでそれが役立ちます。 – Chuck

0

とそのが定義されている場合は以下を参照してください

B.instance_methods(false).include?("a_method") 

そして、我々は、同様にsingleton_methodsを使用するクラスメソッドのために:「a_methodは」Bでオーバーライドされた場合の検出

a = A.new 

a.methods.include?(:method) 
+0

OPはそれがメソッドをオーバーライドするかどうクラスB *内から*を検出する方法を求めています。 クラスAがメソッドを定義することは、クラスBがそれをオーバーライドするかどうかを示していないことを認識しています。 –

+0

これは問題ありませんが、メソッドがBのインスタンスメソッドに(*)*含まれていないことをさらに検出する方法はありますか? – mxgrn

+0

でも、あなたはまだAがメソッドに応答するかどうかを知ることができます。もしそうであれば、Bが同じメソッドを定義していれば、明らかにAのimplementatonをオーバーライドします。 – ennuikiller

0

与えられたオブジェクトbは、 B、あなたはbのすぐ上のスーパークラスはa_methodを持っているかどうかをテストすることができます。テストはメソッド名ではなく、記号やメソッドオブジェクトに対してであることを

b.class.superclass.instance_methods.include? 'a_method' 

お知らせ。

「のでBで上書きされていない」 - ちょうどあなたがAとBの個々のインスタンスにメソッドを定義することができますので、唯一のAで定義されている方法が困難であることを知っている...ので、私はそれが起こっているのだと思いますシステムのすべてのサブクラスとサブインスタンスを切り上げてテストする必要があるため、a_メソッドがAでのみ定義されていることをテストするのは難しいでしょう...

2
class A 
    def m1; end 
    def m2; end 
end 

class B < A 
    def m1; end 
    def m3; end 
end 

obj = B.new 
methods_in_class = obj.class.instance_methods(false) # => ["m1", "m3"] 
methods_in_superclass = obj.class.superclass.instance_methods(false) # => ["m2", "m1"] 
methods_in_superclass - methods_in_class # => ["m2"]