Учитывая следующий допустимый пример Ruby:
"to_i".to_sym.to_proc.call("1")
Чтобы вызвать #to_proc
для символа, создается процесс, который получает один параметр: объект, который должен получить вызов метода, названного символом. Что-то вроде этого:
->(object) {
object.send(:to_i)
}
Что делает &
, так это передает блок, возвращенный #to_proc
, как правильный блок вызова вызываемому методу. При использовании с Enumerable#map
окончательный результат заключается в том, что переданный блок будет вызываться для каждого элемента в коллекции и получать текущий элемент итерации, передаваемый в качестве параметра блоку.
Таким образом, синтаксис ["1", "2"].map(&:to_i)
— это сокращение от чего-то вроде этого:
block = ->(el) {
el.send(:to_i)
}
["1", "2"].map &block
О ваших примерах:
Когда вы попытаетесь вызвать &to_i
в своем примере, Ruby попытается вызвать переменную или метод с именем to_i
. Поскольку он не существует в области (это метод каждого String
в Array
, а не в «глобальной» области), он выдаст ошибку.
О другом примере: "to_i".to_sym.to_proc
преобразует :to_i
в процедуру, которая при вызове с одним параметром попытается вызвать метод, названный в честь символа (:to_i
) для целевого параметра. Это означает, что вы можете использовать &
для преобразования процедуры в «блок вызова»:
["1", "2"].map(&"to_i".to_sym.to_proc)
person
Ricardo Valeriano
schedule
18.01.2016