2012-07-13 8 views
10

Supongamos que aquí hay un código de biblioteca arbitrario que no sé sobre: ​​¿Puedo detectar que un método ha sido anulado?

class Foo 
    def hi 
    end 
end 

class Bar < Foo 
    def hi 
    end 
end 

Y supongamos que tengo un poco de código donde me pasé Bar como parámetro.

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

En el ejemplo anterior, puedo saber que x.hi (donde x referencia a una instancia de Bar) es diferente de Foo#hi?


Sobre la base de la respuesta de Gareth, esto es lo que tengo hasta ahora:

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 

horrible? ¿Maravilloso?

+0

Si bien no es necesariamente relevante, tengo curiosidad por saber por qué quieres hacer esto. –

+0

Además, parece que solo le importa "anular" con respecto a la herencia en lugar de redefinir un método existente en la misma clase? –

Respuesta

9

usted puede hacer esto:

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

estoy lejos de ser un experto en Rubí; No me sorprendería si alguien tiene una mejor manera que esto.

+0

¡Agradable! Acabo de tropezar con lo mismo yo mismo. Y, como usted, esperaré para ver si alguien más viene y nos derriba por este enfoque. Si no, lo aceptaré porque creo que puedo usarlo para lograr lo que busco. –

+0

@DanTao Puede que no importe en su caso, pero si 'Foo' tiene parche de mono, aún así informará que' Foo' es el propietario. –

+0

Realmente no veo cómo podría hacer otra cosa en ese caso. (Y el parche de monos no está * anulando * de todos modos.) ¿Me estoy perdiendo algo? –

0

¡Pregunta interesante! Me preguntaba sobre la misma pregunta. Puede volver a abrir la clase Bar y comprobar quiénes son los antepasados ​​en la ruta de búsqueda de Bar que tienen el método definido.

class Bar < Foo 
    ancestors.each do |ancestor| 
    puts ancestor if ancestor.instance_methods.include?(:hi) 
    end 
end 
Cuestiones relacionadas