2017-09-25 5 views
1

Pour des fins d'apprentissage, j'explore si je peux convertir ces trois appels de méthode:Comment convertir la méthode de proc pour et l'utilisation de la méthode Ruby

Foo::Bar.logger.debug(a) 
Foo::Bar.logger.debug(b) 
Foo::Bar.logger.debug(c) 

dans une seule déclaration en ligne en utilisant l'approche proc &method sténographie :

[a, b, c].each(&method(:'Foo::Bar.logger.debug')) 

.debug ne répond pas .to_proc si naturellement:

NameError: undefined method `Foo::Bar.logger.debug' for class `#<Class:Foo>' 

Cela fonctionne; cependant, mais n'est pas aussi succinct que le premier:

logger = Proc.new { |x| Foo::Bar.logger.debug(x) }                           
[a, b, c].each(&logger) 

Est-il possible que la première approche fonctionne?

+0

Avez-vous lu le message d'erreur ? Quel est le nom de la méthode que le message d'erreur vous indique qu'il ne peut pas trouver? Qu'est-ce que cela vous dit à propos de l'argument que 'method' attend de vous? Que vous dit le message d'erreur à propos de * où * essaie-t-il de trouver cette méthode? Qu'est-ce que cela vous dit sur le fonctionnement de 'method'? Où dit-on quelque chose à propos de ne pas répondre à 'to_proc'? Pourquoi en arrivez-vous à la conclusion que le problème est avec 'to_proc'? –

+0

Je suppose que '[a, b, c] .each {| x | Foo :: Bar.logger.debug (x)} 'serait trop simple? ;-) – Stefan

+0

@ JörgWMittag J'ai lu le message d'erreur mais je ne l'ai pas compris. J'ai eu l'idée de passer '& method' à un func qui accepte un appel de bloc'.to_proc' sur la méthode d'un blog lié à StackOverflow: https://www.skorks.com/2013/04/ruby-ampersand-parameter-demystified/ (section: Le symbole à Proc Trick). Il ne m'est pas venu à l'esprit que la méthode 'method' devait être appelée spécifiquement dans la classe de la méthode. – doremi

Répondre

3

Vous utilisez incorrectement la méthode method. De l'fine manual:

méthode (sym) → Méthode
recherche la méthode nommée en tant que récepteur dans obj, retourner un objet Method (ou élever NameError).

Vous auriez l'habitude de dire

m = some_obj.method(:some_method_name) 

puis travailler avec m. Dire:

method(:Foo::Bar.logger.debug) 

devrait être vous donner un TypeError parce que :Foo est un symbole, pas une classe ou d'un module et d'essayer d'appliquer :: à un symbole n'a pas de sens. Je suppose que vous êtes en train de dire:

method(':Foo::Bar.logger.debug') 

comme cela produira l'erreur que vous voyez. En supposant que c'est le cas, vous essayez en fait d'obtenir une référence à la méthode ':Foo::Bar.logger.debug' dans l'objet self.

Si vous souhaitez une référence à la méthode debug à Foo::Bar.logger vous dirais:

Foo::Bar.logger.method(:debug) 

La combinaison que votre to_proc appel (via &):

[a, b, c].each(&Foo::Bar.logger.method(:debug)) 
+0

Merci pour l'explication approfondie. – doremi

+1

@doremi Vous êtes les bienvenus, apprendre est pourquoi nous sommes ici, nous ne sommes pas ici pour se vanter de ce que nous pensons que nous savons en mettant d'autres personnes vers le bas. –