2009-11-08 11 views
6

decir, que tienen las siguientes 2 clases:detectar que un método no fue anulada

class A 
    def a_method 
    end 
end 

class B < A 
end 

¿Es posible detectar desde dentro (una instancia de) clase B que el método a_method sólo es se define en la superclase, por lo que no se anula en B?

Actualización: la solución

Aunque he marcado la respuesta de Chuck como "aceptada", más adelante Paolo Perrota hizo darme cuenta de que la solución puede parecer ser más simple, y es probable que funcionen con versiones anteriores de Ruby, también.

Detectar si "un_metodo" se anula en B:

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

Y para los métodos de clase que utilice singleton_methods parecida:

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

Respuesta

7

Si está utilizando Ruby 1.8.7 o superior, es fácil con Method#owner/UnboundMethod#owner.

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

¡Muy bien, gracias! Especialmente feliz después de ver la versión de Ruby que originalmente mencionaste pasar de 1.9 a 1.8.7 (que en realidad estoy usando). – mxgrn

+0

Sí, estaba un poco confuso sobre eso. Al principio pensé que funcionaba con 1.8.7, luego vi que 'Method # owner' no estaba en los documentos 1.8.7 ri, así que lo cambié a 1.9, entonces realmente verifiqué si el método existía en 1.8.7 y vi que lo tuve bien la primera vez. Me alegro de que ayude. – Chuck

0

siempre posible para la siguiente y ver si su definido allí:

a = A.new 

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

El PO está pidiendo cómo detectar * desde dentro de la clase B * si se reemplaza el método o no. Sabiendo que la clase A define el método, no dice si la clase B lo anula o no. –

+0

Esto está bien, pero ¿cómo detectar adicionalmente que el método * no * (originalmente) está incluido en los métodos de instancia de B? – mxgrn

+0

bien en b aún se puede ver si A responde al método, si es así y B define el mismo método, entonces obviamente anula la implementación de A – ennuikiller

0

Dado un objeto b que es una instancia de B, puede probar para ver si superclase inmediata b 's tiene a_method:

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

en cuenta que la prueba está en contra del nombre del método, no un símbolo o un objeto método.

"no estar anulado en B" - El simple hecho de saber que el método solo está definido en A es difícil porque puede definir el método en instancias individuales de A y B ... así que creo que va a Sería difícil probar que a_method solo está definido en A, porque tendría que redondear todas las subclases y subinstancias en el sistema y probarlas ...

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"] 
Cuestiones relacionadas