Je voudrais spécifier de manière dynamique la classe mère pour une classe dans Ruby. Considérons ce code: ni le parent Ma deuxième question est la suivante: Dois-je besoin em> pour transmettre le premier argument à ni la définition de la classe code> de code> Spécifie une classe mère, de sorte qu'ils héritent tous les deux d'objet. Ma première question est la suivante: que devrais-je faire dans
agent.hook_up code> afin de faire
parent code> la superclasse de
enfant code> (donc par exemple < Code> Enfant Code> Les objets peuvent hériter de la méthode "bar"). P>
Agent. harok_up code> ou existe une manière que la méthode
harok_up code> peut déterminer par programme par programme à partir de laquelle il a été appelé? p> p>
7 Réponses :
Peut-être que vous recherchez ce puisque le parent est un argument de classe.Nouveau, vous pouvez l'échanger avec d'autres classes. P> J'ai utilisé cette technique avant d'écrire certains types de tests. Mais j'ai du mal à penser à de nombreuses bonnes excuses pour faire une telle chose. p> Je soupçonne ce que vous voulez vraiment est un module. p> Bien sûr, il n'y a pas besoin de l'agent du tout p>
Merci Joshua. Comme il semble que je ne puisse pas changer la chaîne d'héritage au moment de l'exécution, je finirai probablement à utiliser une variation de votre première option dans ma solution. J'apprécie le temps que vous avez réagi.
Une autre chose que vous pouvez regarder, si c'est vraiment i> ce que vous voulez faire, est Change_class écrit par Ryan Davis. Voici la vidéo où il introduit le code à 5:00 rubyconf2008.confreaks.com/evil-code .html Voici la page d'accueil du projet. Seatlerb.rubyforge.org/change_class Note la responsabilité "Oui, c'est dangereux ... Don ' t viens me pleurer si votre ordinateur s'allume. "
Joshua vous a déjà donné une excellente liste d'alternatives, mais pour répondre à votre question: vous ne pouvez pas changer la superclasse d'une classe après la création de la classe dans Ruby. Ce n'est tout simplement pas possible. P>
@Borromakot Statut du défi?
@Borromakot, sauf si vous remplissez leurs emplacements de mémoire :)
Comme indiqué déjà, vous devez probablement regarder des modules ou créer de manière dynamique des cours. Cependant, vous pouvez utiliser Evil-Ruby pour changer la superclasse. Il y a même un Fourche pour Ruby 1.9 disponible. Cela ne fonctionne que pour l'IRM. Devrait être facile à construire sur Rubinius (méthodes de compensation des caches serait le problème principal), aucune idée de Jruby. Voici le code:
require 'evil' class Agent def self.hook_up(calling_class, desired_parent_class) calling_class.superclass = desired_parent_class end end class Parent def bar puts "bar" end end class Child def foo puts "foo" end Agent.hook_up(self, Parent) end Child.new.bar
Je suppose que l'utilisation du "mal" serait probablement fronçée dans le code de production :-) Créer de manière dynamique une classe est probablement la solution que je vais finir. Merci!
Ruby 1.9 Seulement: (1,8 est similaire, mais utilisez rclass (auto) -> super à la place)
SimpleDelegator classe (dans le délégué bibliothèque) peut aider, à condition que c'est suffisant que l'objet compensation comme em> la classe de base plutôt que soit une instance de em> la classe de base. require 'delegate'
class Agent < SimpleDelegator
def baz
puts "baz"
end
end
class BarParent
def bar
puts "bar"
end
end
class FooParent
def foo
puts "foo"
end
end
agent = Agent.new(FooParent.new)
agent.baz # => baz
agent.foo # => foo
agent.__setobj__(BarParent.new)
agent.baz # => baz
agent.bar # => bar
regarde sur ce et le sélecteur de classe: p> donc, lorsque l'instance J'espère aider .. Bye! P> p> myClass code> Sera hériter d'une classe dynamique en fonction de
orm code> et
modèle code>.
Assurez-vous de définir les deux dans un module. Ça marche bien dans public_activité gem ( Exemple de sélecteur ). P>
Je sais que cette question est assez ancienne et a déjà de bonnes réponses. Cependant, je manque toujours une solution certaine.
Si votre intention n'est pas d'attribuer de manière dynamique la superclasse, mais plutôt de créer un crochet pour exécuter du code sur héritage ( XY Problème ). Il y a une façon de faire cela. P>
Hérité (sous-classe) h3>
rappel invoqué chaque fois qu'une sous-classe de la classe actuelle est créée. P>
Exemple: P>
New subclass: Bar New subclass: Baz
Si vous définissez ou changez de manière dynamique le parent d'une classe, c'est une affirmation raisonnable que votre modèle d'objet ne reflète pas une vraie relation une relation i>. Une solution plus appropriée est probablement la composition.
Vous devriez préciser si c'est un exercice de pensée, ou pourquoi vous voudriez utiliser cela dans la pratique. Les langages réfléchissants dynamiques ne veulent pas dire qu'il est propre pour changer de manière dynamique l'héritage. Avec un grand pouvoir (expressif), vient une grande responsabilité :)
@cletus Je ne suis pas un grand fan d'héritage en général mais pour le problème que je regarde actuellement, l'héritage et la relation est une relation parfaitement décrivant parfaitement la relation. Le seul problème est qu'un objet ne saura pas ce qu'il "est" jusqu'à ce que le temps d'exécution.