Ответ 1
Здесь несколько движущихся частей, но имя для того, что происходит, - это 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
этого элемента.