Rilevare che un metodo non è stato sovrascritto

voti
6

Di ', ho le seguenti 2 classi:

class A
  def a_method
  end
end

class B < A
end

È possibile rilevare dall'interno (un'istanza) classe B che il metodo a_methodè solo definito nella superclasse, quindi non essendo override in B?

Aggiornamento: la soluzione

Mentre ho segnato la risposta di Chuck come accettato, poi Paolo Perrota mi ha fatto capire che la soluzione apparentemente può essere più semplice, e probabilmente funzionerà con le versioni precedenti di Ruby, anche.

Rilevare se a_method viene sovrascritto in B:

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

E per metodi di classe che usiamo singleton_methodssimile:

B.singleton_methods(false).include?(a_class_method)
È pubblicato 08/11/2009 alle 20:56
fonte dall'utente
In altre lingue...                            


4 risposte

voti
0

si può sempre al seguente e vedere se ci definito:

a = A.new

a.methods.include?(:method)
Risposto il 08/11/2009 a 21:00
fonte dall'utente

voti
0

Dato un oggetto bche è un'istanza di B, è possibile verificare per vedere se b's superclasse immediata ha a_method:

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

Si noti che il test è contro il nome del metodo, non un simbolo o un oggetto metodo.

"quindi non essere ignorata in B" - Solo sapendo che il metodo è definito solo in A è difficile perché è possibile definire il metodo su un individuo istanze di A e B ... quindi penso che sarà difficile per testare che a_method è definito solo su a, perché dovreste radunare tutte le sottoclassi e subinstances nel sistema e testarli ...

Risposto il 08/11/2009 a 21:34
fonte dall'utente

voti
7

Se stai usando rubino 1.8.7 o superiore, è facile con Method#owner/ UnboundMethod#owner.

class Module
  def implements_instance_method(method_name)
    instance_method(method_name).owner == self
    rescue NameError
    false
  end
end
Risposto il 08/11/2009 a 21:43
fonte dall'utente

voti
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"]
Risposto il 09/11/2009 a 12:27
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more