2016-04-09 1 views
-1

Lorsque je tente de passer un bloc arbitraire à la méthode each_with_object, elle soulève une erreur:Le passage d'un proc comme un bloc à une méthode

%w(foo bar baz).each_with_object([]) &->(i,m) { m << i.upcase } 
# => NoMethodError: undefined method `&' for #<Enumerator: ["foo", "bar", "baz"]:each_with_object([])> 

Lorsque je tente de passer un bloc à inject méthode, il soulève aussi une erreur:

%w(foo bar baz).inject('') &->(m,i) { m + i.upcase } 
# => NoMethodError: undefined method `' for "foo":String 

Mais cela fonctionne si je ne passe pas une valeur initiale:

%w(foo bar baz).split.inject &->(m,i) { m + i.upcase } 

Et cela fonctionne aussi quand je passe un bloc à la méthode each.

%w(foo bar baz).each &->(i) { puts i.upcase } 
# FOO 
# BAR 
# BAZ 

Quelqu'un peut-il expliquer ce comportement? Comment puis-je passer des blocs arbitraires aux deux premiers exemples?

+0

Qu'est-ce que cela a à voir avec l'IDE Code :: Blocks C++? –

+0

@ JörgWMittag Désolé, j'ai ajouté cette balise par erreur. – sawa

Répondre

4

Le préfixe d'argument & transforme un argument dans le bloc de la méthode (en appelant to_proc). Comme il est un argument, il faut aller à l'intérieur des parens si vous les utilisez, par exemple

%w(foo bar baz).each_with_object([], &->(i,m) { m << i.upcase }) 

Actuellement, rubis interprète le & comme l'opérateur binaire, et en essayant de le faire:

(%w(foo bar baz).each_with_object([]) & (->(i,m) { m << i.upcase })) 

D'où l'erreur. Je ne suis pas sûr pourquoi vous ne faites pas juste:

%w(foo bar baz).each_with_object([]) { |m,i| m << i.upcase } 
+0

C'était juste un exemple, ma structure de bloc conserve une logique plus difficile. Merci – DreamWalker

+0

"transforme un argument dans le bloc de la méthode": juste un libellé, mais pour être plus précis, il appelle la méthode to_proc sur l'argument et le passe à la méthode appelée en tant que bloc. – mudasobwa