Здесь есть несколько движущихся частей, но название происходящего - Symbol#to_proc
преобразование. Оно является частью Ruby 1.9 и выше, а также доступно, если вы используете более поздние версии Rails.
Во-первых, в Ruby :foo
означает "символ foo
", так что на самом деле перед вами два отдельных оператора, а не один большой &:
.
Когда вы говорите foo.map(&bar)
, вы говорите Ruby: "Отправьте сообщение объекту foo
, чтобы вызвать метод map
, с уже определенным мной блоком под названием bar
". Если bar
еще не является объектом Proc
, Ruby попытается сделать его таковым.
Здесь мы передаем не блок, а символ под названием bar
. Поскольку у нас есть неявное преобразование to_proc
, доступное для Symbol
, Ruby видит это и использует его. Оказывается, это преобразование выглядит так:
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
Это создает proc
, который вызывает метод с тем же именем, что и символ. Складывая все вместе, используя ваш исходный пример:
array.map(&:to_i)
Это вызывает .map
на массиве, и для каждого элемента в массиве возвращает результат вызова to_i
на этом элементе.