2010-11-03 6 views
0

Je ne sais pas si c'est réellement possible, mais je n'ai pas été capable de trouver une réponse claire n'importe où. De plus, j'ai du mal à définir ma question en termes de «termes de recherche». Donc, je suis désolé si cela a déjà été répondu ailleurs, 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 qui n'est pas définie dans l'emplacement où la Proc est en cours de définition. Ensuite, je voudrais mettre cette instance dans une autre classe qui a la méthode, et exécuter celui-là avec les arguments fournis.Ruby Proc: Invoquant la méthode de la classe A à partir de la classe B, et en utilisant la «méthode» de la classe B

Voici un échantillon de ce que je veux accomplir, mais je ne sais 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 MyClassA plutôt que celui MyClassB. Cependant, est-il possible de faire en sorte que la commande run invoque la méthode d'instance run de MyClassB?

Répondre

2

Il y a deux problèmes avec votre code:

  1. MyClassA.new ne retourne pas la valeur de initialize il renvoie toujours une instance de MyClassA.

  2. Vous ne pouvez pas simplement appeler le proc, vous devez utiliser la méthode instance_eval pour l'exécuter dans le contexte de MyClassB

Voici votre code corrigé pour travailler comme 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" 
+0

Merci m8! Ouais désolé c'était un mauvais exemple de ce que j'essayais de faire. Ce n'était pas vraiment la question pratique que j'avais, mais celle-ci était un peu complexe à ajouter ici, alors j'ai écrit cela rapidement. Fait l'erreur avec la méthode d'initialisation qui, comme vous l'avez dit, renvoie bien sûr l'instance. Merci pour la solution! :) –

Questions connexes