8

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!

toch
  • 3,905
  • 2
  • 25
  • 34
David
  • 7,028
  • 10
  • 48
  • 95

1 Answers1

12

& 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).

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • I see. Very, very interesting! In Ruby, I find that many things are very simple to do, as I did with my select. You went forward and wrote `{|elem| elem.send :even?}` Is this in essence what my block is doing in the background? Changing itself into that format and then doing whatever computation it is meant to do? So many different ways to do things in Ruby. I'm curious. – David May 17 '13 at 09:36
  • @David: yes, that's what `select(&:even?)` does under the hood. – Sergio Tulentsev May 17 '13 at 09:39
  • 1
    @David don't forget to accept the answer, if it does indeed answer the question! – vgoff May 17 '13 at 10:17
  • 1
    Answer from @SergioTulentsev = auto +1 ;) – Anand Shah May 17 '13 at 11:19