Most of us use this without knowing how it works:

a = [1, 2, 3, 4]
a.inject { |acc, num| acc + num } # => 10

# Same as above but much more beautiful
a.inject(&:+) # => 10

Yes it adds the numbers, but how does this work?

Actually, whenever Ruby finds an &parameter it expects the parameter to be a Proc object. If not, Ruby tries to convert it into a proc by calling to_proc method on it. Turns out the Symbol class has a handy to_proc method which returns a proc which sends the method to receiving object. Something like this:

class Symbol
  def to_proc
    proc { |obj, *args| obj.send(self, *args) }
  end
end
# => :to_proc

a = [1,2,3]
a.inject(&:+) # => 6
a.map(&:to_s) # => ["1", "2", "3", "4"]

to_proc returns a simple Proc which sends the symbol(self) to the object yielded by the enumerator.

This code is for representation of how Symbol#to_proc works, actual code is written in C and is much more sophisticated.

References:

  1. https://ruby-doc.org/core-2.4.0/Symbol.html#method-i-to_proc