web-dev-qa-db-fra.com

Comment appeler une méthode de classe super

J'ai deux classes A et B. La classe B remplace la méthode foo de la classe A. La classe B a une méthode bar dans laquelle je souhaite appeler la méthode foo de la super classe. Quelle est la syntaxe pour un tel appel?

class A    
 def foo
   "hello"
 end    
end


class B < A
 def foo
  super + " world"
 end

 def bar
   # how to call the `foo` method of the super class?
   # something similar to
   super.foo
 end
end

Pour les méthodes de classe, je peux appeler les méthodes jusqu'à la chaîne d'héritage en préfixant explicitement le nom de la classe. Je me demande s'il existe un idiome similaire pour les méthodes d'instance.

class P
 def self.x
   "x"
 end
end

class Q < P
 def self.x
   super + " x"
 end

 def self.y
   P.x
 end
end

Edit Mon cas d'utilisation est général. Pour un cas spécifique, je sais que je peux utiliser la technique alias. Il s'agit d'une fonctionnalité courante en Java ou en C++. Je suis donc curieux de savoir s'il est possible de le faire sans ajouter de code supplémentaire.

27
Harish Shetty

Dans Ruby 2.2, vous pouvez maintenant utiliser Method#super_method

Par exemple:

class B < A
  def foo
    super + " world"
  end

  def bar
    method(:foo).super_method.call
  end
end

Réf: https://bugs.Ruby-lang.org/issues/9781#change-48164 et https://www.Ruby-forum.com/topic/5356938

28
zlx_star

Tu peux faire:

 def bar
   self.class.superclass.instance_method(:foo).bind(self).call
 end
23
Sony Santos

Dans ce cas particulier, vous pouvez simplement alias :bar :foo avant def foo dans class B pour renommer l’ancienne foo en bar, mais vous pouvez bien sûr aliaser le nom de votre choix et l’appeler de cette manière. Cette question a d'autres moyens de le faire plus loin dans l'arbre de l'héritage.

13
Arkku

Vous pouvez alias old_foo foo avant de le redéfinir pour conserver l'ancienne implémentation sous un nouveau nom. (Techniquement, il est possible de prendre l'implémentation d'une super-classe et de la lier à une instance d'une sous-classe, mais c'est hacky, pas du tout idiomatique et probablement assez lent à démarrer.)

5
Chuck