2009-08-09 6 views
47
 
class A 
    def a 
    puts 'in #a' 
    end 
end 

class B < A 
    def a 
    b() 
    end 
    def b 
    # here i want to call A#a. 
    end 
end 

Répondre

79
class B < A 

    alias :super_a :a 

    def a 
    b() 
    end 
    def b 
    super_a() 
    end 
end 
+0

Pour alias une méthode de classe, voir http://stackoverflow.com/questions/2925016/alias-method-and-class-methods-dont-mix –

+0

Est-il possible que 'alias' ait été renommé en [' alias_method'] (http://apidock.com/ruby/Module/alias_method) depuis que cette réponse a été écrite? –

+0

@JaredBeck il a vraiment été renommé. Alors maintenant, il devrait être: alias_method: super_a: un –

29

Il n'y a pas de bonne façon de le faire, mais vous pouvez faire A.instance_method(:a).bind(self).call, qui va fonctionner, mais est moche.

Vous pouvez même définir votre propre méthode objet pour agir comme super en java:

class SuperProxy 
    def initialize(obj) 
    @obj = obj 
    end 

    def method_missing(meth, *args, &blk) 
    @obj.class.superclass.instance_method(meth).bind(@obj).call(*args, &blk) 
    end 
end 

class Object 
    private 
    def sup 
    SuperProxy.new(self) 
    end 
end 

class A 
    def a 
    puts "In A#a" 
    end 
end 

class B<A 
    def a 
    end 

    def b 
    sup.a 
    end 
end 
B.new.b # Prints in A#a 
+8

@klochner Je suis en désaccord, cette solution était exactement ce que je avais besoin ... raison: je voulais méthode super génériquement appel d'une méthode différente, mais sans la nécessité d'un seul alias tous que je voulais être en mesure pour ce faire, donc une façon générique d'invoquer super est très utile –

+3

Compliqué pour définir une fois, simple de l'appeler beaucoup de fois. C'est mieux que l'inverse. – nertzy

0

Si vous n'avez pas besoin explicitement appeler A # A # B de b, mais plutôt besoin pour appeler A # a de B # a, ce qui est effectivement ce que vous faites par B # b (à moins que votre exemple ne soit pas assez complet pour démontrer pourquoi vous appelez de B # b, vous pouvez juste appel super à partir de B # a, comme c'est parfois fait dans les méthodes initialize.Je sais que c'est un peu évident, je voulais juste clarifier pour les nouveaux arrivants Ruby que vous n'avez pas à alias (en particulier, cela est parfois appelé un "alias autour") dans tous les cas e.

class A 
    def a 
    # do stuff for A 
    end 
end 

class B < A 
    def a 
    # do some stuff specific to B 
    super 
    # or use super() if you don't want super to pass on any args that method a might have had 
    # super/super() can also be called first 
    # it should be noted that some design patterns call for avoiding this construct 
    # as it creates a tight coupling between the classes. If you control both 
    # classes, it's not as big a deal, but if the superclass is outside your control 
    # it could change, w/o you knowing. This is pretty much composition vs inheritance 
    end 
end 
Questions connexes