2010-12-29 21 views
15

È possibile fare qualcosa come super.super nel metodo sovrascritto? Cioè, per bypassare il super genitore diretto e chiamare super "nonni"?Chiamare il super metodo di super

+0

... Non posso fare a meno di pensare che questa domanda sia, in effetti, una canzone di [They Might Be Giants] (http://en.wikipedia.org/wiki/They_Might_Be_Giants) ... Oo .. .scusa. –

+7

Quindi, in pratica, vuoi un metodo 'superduper'? :) –

risposta

19

questo non è consigliato, ma ciò che si vuole è possibile in questo modo:

grandparent = self.class.superclass.superclass 
meth = grandparent.instance_method(:the_method) 
meth.bind(self).call 

Questo funziona attraverso il collegamento della classe nonno, quindi chiamando instance_method su di esso per ottenere una UnboundMethod che rappresenta la versione del nonno di the_method. Quindi utilizza UnboundMethod#bind e Method#call per chiamare il metodo del nonno sull'oggetto corrente.

-1

Considerando che questo sta infrangendo uno dei principi di OOP (incapsulamento), spero che non sia possibile. Anche il caso in cui tu stia cercando di farlo parla di un problema con il tuo design.

+0

Vero, ero solo curioso dal momento che tutto sembra possibile in Ruby. – Vincent

+1

Mi dispiace, ma hai sentito parlare dei diamanti ereditari? Ecco come possono essere risolti in Ruby. Quindi non facciamo diamanti ereditari, o cambiamo Ruby per accontentarli, si potrebbe dire. Non discuterò. Quello che dici potrebbe valere nel mondo ideale. Ma nel mondo reale, stai lavorando con il codice scritto da programmatori cattivi, che devi collegare insieme senza avere il diritto di modificarlo. E questo è ciò a cui servono questi cacciaviti. –

0

è possibile modificare gli argomenti del metodo per consentire un tipo di parametro facoltativo 'pass to parent'. nella super classe di tuo figlio, controlla questo parametro e, in tal caso, chiama super da quel metodo e ritorna, altrimenti permetti all'esecuzione di continuare.

class Grandparent; def method_name(opts={}); puts "Grandparent called."; end; end 
class Parent < Grandparent 
def method_name(opts={}) 
    return super if opts[:grandparent] 
    # do stuff otherwise... 
    puts "Parent called." 
end 
end 
class Child < Parent 
def method_name(opts={}) 
    super(:grandparent=>true) 
end 
end 

ruby-1.9.2-p0 > Child.new.method_name 
Grandparent called. 
    => nil 

altrimenti sono d'accordo con @Femaref, solo b/c qualcosa è possibile non significa che sia una buona idea. riconsiderare il tuo design se pensi che sia necessario.

Problemi correlati