Ruby Proc: Méthode invocation de la classe A partir de la classe B, et en utilisant « la méthode » de la classe B
-
28-09-2019 - |
Question
Je ne suis pas sûr que ce soit effectivement possible, mais je ne pouvais pas trouver une réponse claire de nulle part. Aussi je trouve qu'il est difficile de définir ma question simple "des termes de recherche. Je suis donc désolé si cela a déjà été répondu à un autre endroit, je ne pouvais pas le trouver.
Ce que je voudrais savoir est s'il est possible de créer un Proc qui contient une méthode non définie à l'endroit où le Proc est défini. Ensuite, je voudrais mettre cette instance dans une autre classe qui a la méthode, et exécuter QU'un avec les arguments fournis.
Voici un échantillon de ce que je veux accomplir, mais ne savent pas comment.
class MyClassA
# This class does not have the #run method
# but I want Class B to run the #run method that
# I invoke from within the Proc within this initializer
def initialize
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
my_class_a_object.call
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.new
MyClassB.new(my_class_a_object)
L'erreur suivante est produite
NoMethodError: undefined method for #<MyClassA:0x10017d878>
Et je pense que je comprends pourquoi, il est parce qu'il tente d'invoquer la méthode run
sur l'instance de MyClassA
plutôt que celui MyClassB
. Cependant, est-il un moyen que je pourrais faire la commande run
Invoke méthode d'instance MyClassB
de run
?
La solution
Il y a deux problèmes avec votre code:
-
MyClassA.new
ne retourne pas la valeur deinitialize
il renvoie toujours une instance deMyClassA
. -
Vous ne pouvez pas simplement appeler le proc, vous devez utiliser la méthode
instance_eval
pour l'exécuter dans le contexte deMyClassB
Voici votre code corrigé au travail que vous voulez:
class MyClassA
def self.get_proc
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
instance_eval(&my_class_a_object)
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.get_proc
MyClassB.new(my_class_a_object) #=> "something great"