Когда вы префиксите последний аргумент вызова с помощью &
, вы ясно даете понять, что отправляете блок, а не normal аргумент. Хорошо, в method(&:something)
, :something
является символом, а не proc , поэтому Ruby автоматически вызывает метод to_proc
, чтобы получить реальный блок. И ребята из Rails (а теперь и ванильный Ruby) ловко определили его как:
class Symbol
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
end
Вот почему вы можете сделать:
>> [1, 2, 3].map(&:to_s) # instead of [1, 2, 3].map { |n| n.to_s }
=> ["1", "2", "3"]
[править] Примечание: когда вы понимаете, что эта конструкция - не синтетический сахар, а универсальная инфраструктура, которую предоставляет Ruby, ничто не мешает вам реализовать свой собственный to_proc
для других классов. Никогда не чувствовал себя ограниченным, потому что &:method
не допускал никаких аргументов?
class Array
def to_proc
proc { |obj, *args| obj.send(*(self + args)) }
end
end
>> ["1", "F", "FF"].map(&[:to_i, 16])
=> [1, 15, 255]