2010-12-13 12 views
0

Es gibt eine Methode in einer Bibliothek, die ich nicht kontrollieren kann und die einen Block benutzt, um wundervolle Dinge zu tun. Jetzt möchte ich einige Überladungen erstellen, um mein Leben noch einfacher zu machen, aber ich kann nicht herausfinden, wie ich es so machen kann, wie ich es möchte.Eine Ruby-Methode verbessern

Hier ist, was ich bisher:

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 

Die ClassNotDefinedByMe im lib ist und so ist die awesome_method. Die awesome_method nimmt einen Block und macht sinnvolle Dinge mit 0 oder 1 Parameter für diesen Block. Bei jeder anderen Anzahl von Argumenten werden Ausnahmen ausgelöst. Ich habe das oben geschrieben, um die Möglichkeit hinzuzufügen, 2 oder 3 Parameter im Block zu verwenden, und alles funktioniert gut, außer dass ich jetzt enhanced_awesome_method statt awesome_method anrufen muss.

Beispiele für weitere Klärung (x ist eine Instanz der 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" } 

Man könnte argumentieren, dass es eine gute Sache ist, dass ich einen neuen Namen für meine verbesserte Methode verwenden, so dass es offensichtlich, dass es eine andere Methode ist, aber ich würde wirklich gerne awesome_method durch meine ganz ersetzen. Es wird keinen vorhandenen Code brechen, da das Verhalten für die Fälle mit 0 und 1 identisch ist und bis jetzt die einzigen legalen waren.

Also, das Problem, das ich renne ist, dass, wenn ich meine Methode awesome_method benennen und es einen Block mit 0 oder 1 Parameter übergeben, wird es sich für immer nennen. Wenn dies ein Fall von Vererbung wäre, würde ich es lösen, indem ich super.awesome_method aufrufen, aber was kann ich in diesem Fall tun, wenn ich einfach die Klasse selbst geändert habe?

Antwort

3

Verwenden Sie das Schlüsselwort alias, um eine alias der ursprünglichen Funktion zu machen, dann können Sie die Methode, die einen Aufruf der Alias-Methode aufruft, außer Kraft setzen.

zB:

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

Süß, arbeitete wie ein Charme. Vielen Dank! – Jakob

0

Was Sie tun möchten, ist method aliasing genannt, aber es die ursprüngliche Methode ersetzt.