Как стать автором
Обновить

Унарный амперсанд

Время на прочтение 1 мин
Количество просмотров 5K
Расскажу как в Ruby работает такая элегантная конструкция:

User.all.map &:name           # получить массив имен пользователей

вместо

User.all.map { |user| user.name }

Сначала кажется что это свойство перечисляемых классов, но на самом деле это не так.

Магия #1.


Когда ruby встречает амперсанд (&) в последнем аргументе вызова метода,
то пытается превратить его в выполняемый блок кода (Proc). Например:

a = (1..10).to_a
a.map { |n| n*n }             # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l = lambda { |n| n*n }
a.map &l                      # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


Магия #2.


Ruby, встречая амперсанд, превращает обьект в выполняемый блок через вызов метода #to_proc.

И вот он главный сюрприз, вызывая #to_proc у Symbol мы получаем примерно следующий блок кода:

lambda { |x| x.send(self) }


То есть Symbol#to_proc возвращет именно тот блок, который мы от него ожидали, потому что он в таком виде уже определен в классе Symbol.

UPD. Примерчик


Такое свойство Symbol дает удивительную возможность вызывать методы, подставляя объекты в качестве параметров:

:upcase.to_proc.call "asdad"     # => "ASDAD"


Материалы по теме


blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand
weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html
en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls#The_ampersand_.28.26.29
m.onkey.org/let-s-start-with-wtf
Теги:
Хабы:
+54
Комментарии 17
Комментарии Комментарии 17

Публикации

Истории

Работа

Ruby on Rails
12 вакансий

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн