2010-12-13 36 views
0

Il existe une méthode dans une bibliothèque hors de mon contrôle qui utilise un bloc pour faire des choses merveilleuses. Maintenant, je voudrais créer quelques surcharges pour rendre ma vie encore plus facile, mais je n'arrive pas à comprendre comment le faire fonctionner comme je veux.Amélioration d'une méthode Ruby

Voici ce que j'ai jusqu'à présent:

class ClassNotDefinedByMe 
    def enhanced_awesome_method(&block) 
    if block.arity < 2 
     awesome_method(&block) 
    else 
     # Doing my own extensions here. 
     # This part is not the issue. 
    end 
    end 
end 

Le ClassNotDefinedByMe est dans le répertoire lib et ainsi est le awesome_method. Le awesome_method prend un bloc et fait des choses significatives avec 0 ou 1 paramètre pour ce bloc. Tout autre nombre d'arguments entraîne l'apparition d'exceptions. J'ai écrit ce qui précède pour ajouter la possibilité d'utiliser 2 ou 3 paramètres dans le bloc et tout fonctionne bien, sauf que maintenant je dois appeler enhanced_awesome_method au lieu de awesome_method.

Exemples pour plus de précisions (x est une instance de la ClassNotDefinedByMe):

# These two comes from the library: 
x.awesome_method{  puts "works" } 
x.awesome_method{ |i| puts "also works, the argument is #{i}" } 

# Now I can do this: 
x.enhanced_awesome_method{ |i,j| puts "oh, two arguments! cool." } 
x.enhanced_awesome_method{ |i,j,k| puts "three arguments, how bold!" } 

# But I want to be able to do this: 
x.awesome_method{   puts "still works" } 
x.awesome_method{ |i|  puts "still works" } 
x.awesome_method{ |i,j| puts "still works" } 
x.awesome_method{ |i,j,k| puts "still works" } 

On pourrait dire que c'est une bonne chose que je dois utiliser un nouveau nom pour ma méthode améliorée, de sorte qu'il devient apparemment que c'est une méthode différente, mais je voudrais vraiment remplacer awesome_method avec le mien tout à fait. Il ne casse aucun code existant, car le comportement est identique pour les cas de paramètres 0 et 1 et ceux-ci étaient les seuls légaux jusqu'à maintenant.

Donc, le problème que je rencontre est que si je nomme ma méthode awesome_method et lui passe un bloc avec 0 ou 1 paramètre, il s'appellera pour toujours. Si c'était un cas d'héritage, je le résoudrais en appelant le super.awesome_method, mais que puis-je faire dans ce cas quand j'ai simplement modifié la classe elle-même?

Répondre

3

Utilisez le mot-clé alias pour créer un alias de la fonction d'origine, puis vous pouvez remplacer la méthode qui appelle la méthode d'alias.

par exemple:

class ClassNotDefinedByMe 
    alias :old_awesome_method :awesome_method 

    def awesome_method(&block) 
     if block.arity < 2 
      old_awesome_method(&block) 
     else 
      # Awesome stuff here 
     end 
    end 
end 
+0

Doux, travaillé comme un charme. Merci! – Jakob

0

Ce que vous essayez de faire est appelé method aliasing, mais il ne remplace la méthode originale.