2015-06-15 6 views

ответ

2

Когда вы говорите :method, вы используете хороший синтаксический сахар в рубине, который создает новый объект Symbol. Когда вы бросаете амперсанд перед ним (&:method), вы используете другой кусок сахара. Это вызывает метод to_proc на символе.

Таким образом, эти две вещей идентичны:

method_proc = &:method 

sym = :method 
method_proc = method.to_proc 

Какая разница между этим и другим использованием? Ну, у respond_to? есть один аргумент - символ. Таким образом, мы можем пройти :method, и все будет хорошо и денди. (Интересно, что объекты отвечают методу method, но это гораздо более запутанный вопрос).

Для сравнения, итераторы Enumerable (например, map, select и т. Д.) Принимают блок. Когда мы передаем Proc, он правильно интерпретируется как этот блок. Таким образом, эти два фрагмента кода эквивалентны:

[1,2,3].map { |i| i.even? } 
[1,2,3].map(&:even?) 

Эта эквивалентность немного сбивает с толку, потому что, конечно, символ не имеет представления о том, что есть even? метод где-то. Чтобы поиграть с ним, я использовал evenproc = :even?.to_proc для проверки полученного результата. Он реализован в C (по крайней мере, в рубине MRI) и не хочет отказываться от своего источника. Однако его arity - это -1, что означает, что он принимает один необязательный аргумент arg. Мое предположение, что он делает что-то вроде этого:

def to_proc 
    method_name = self.to_s 
    ->(a) { a.send(method_name) } 
end 

я мог выкопать дальше, но я думаю, что мы уже прошли мимо этого вопроса. ;) Удачи!

Смежные вопросы