D'autres vous ont déjà dit de créer une sous-classe. Mais pour répondre à votre question littérale, nous devrions nous occuper de UnboundMethod
objets :
class Object
def kokot; 'kokot' end
end
o = Object.new
o.kokot
#=> kokot
3.kokot
#=> kokot
Jusqu'à présent, tout va bien. Redéfinissons maintenant kokot
méthode sur Numeric
:
class Numeric
def kokot; 'pica' end
end
o.kokot
#=> kokot
3.kokot
#=> pica
Mais que se passe-t-il si nous décidons que les nouveaux kokot
est excellente pour les nombres, mais les nombres complexes devraient continuer à utiliser l'ancienne méthode kokot
méthode. Nous pouvons procéder de la manière suivante :
um = Object.instance_method :kokot
#=> #<UnboundMethod: Object#kokot>
Complex( 2, 3 ).kokot # gives the redefined kokot method
#=> pica
Complex.module_exec { define_method :kokot, um }
# Now we've just bound the old kokot to Complex
Complex( 2, 3 ).kokot
#=> kokot
En bref, il existe un moyen de "copier et coller" des méthodes entre classes apparentées. La cible doit être une sous-classe de la méthode source non liée. Méthode #source_location
indique le fichier et la ligne où #kokot
a été défini :
um.source_location
#=> ["(irb)", 2]
Pour les méthodes intégrées, #source_location
retours nil
. Dans Ruby 2.0, RubyVM
a une méthode #disassemble
:
RubyVM::InstructionSequence.disassemble( um )
#=> ( program listing goes here )
Dans tous les cas, le bytecode Ruby n'est pas très beau à regarder. Pour en revenir à vos besoins initiaux, même pas #define_method
o UnboundMethod#bind
peut lier des méthodes à des objets incompatibles. Il n'est pas possible de contourner ce problème par des astuces telles que la redéfinition de l'objet #kind_of?
il faudrait tricher avec la fonction CLASS_OF() dans le code natif...
Parmi les pierres précieuses disponibles, Sourcify , RubyParser y Sorcier sont intéressantes. (Merci, @Casper.) En les utilisant, on pourrait théoriquement transplanter du code entre des objets incompatibles par l'intermédiaire de #eval
-ling méthode extraite source. Même si elle est longue, cette technique ne permet pas un véritable transfert de méthode, car elle échoue lorsque la source n'est pas disponible au moment de l'exécution (p. ex. source auto-modifiante).