Ruby trying to grasp a new notation. (inject(: ) v

2019-03-28 01:42发布

问题:

So, I've just learned that instead of writing things like:

[1,2,3,4,5].inject {|x,y| x + y} => 15

I could write

[1,2,3,4,5].inject(:+) => 15

I also learned that instead of writing

[1,2,3,4,5].select {|x| x.even?} => [2,4]

I could write

[1,2,3,4,5].select(&:even?) => [2,4]

My question is why one (select) uses the & and the other one (inject) doesn't. I'm sure that the : are because even? and + are treated at symbols, but I'd love clarification behind why the & is used in one and why the : are used.

Also, I'm aware that I could do these notations on more than just inject and select.

Many thanks!

回答1:

& operator in this case converts a symbol to a proc. So the code does this under the hood:

[1,2,3,4,5].select {|elem| elem.send :even? } # => [2, 4]

Implementation of inject method recognizes the need for these shortcut method specification and adds a special handling for when symbol is passes as a parameter. So, in this case, it basically does what & operator does.

why one (select) uses the & and the other one (inject) doesn't

Because nobody implemented select this way. Ruby is open-source, they may even accept your patch. Go and fix this :)

P.S.: But if it were up to me, I would instead remove inject's special handling. It feels a little bit redundant and confusing in presence of Symbol#to_proc (that's what & operator uses).