Upload
alex-mikitenko
View
166
Download
4
Embed Size (px)
Citation preview
LESSON 3: BLOCK, PROC AND LAMBDA
DYNAMIC RUBY
BLOCKS
BLOCKS
BLOCK
BLOCKS
В других языках схожие синтаксические конструкции называют “замыкания”. В некотором смысле блоки ведут себя как анонимные методы.
BLOCKS
Нечто похожее на метод
▸ имеет свою локальную область видимости переменных;
▸ имеет возвращаемое значение;
▸ может принимать аргументы;
▸ Имеют обособленный контекст как в отношении переменных, так и возвращаемого значения (с некоторой спецификой);
▸ имеет доступ к переменным, которые были объявлены в том же контексте, в котором был описан блок;
▸ ключевое слово return не используется - в контексте main оно вызовет exception LocalJumpError, в контексте любой иной функции приведет к выходу из нее;
▸ при вызове можно передавать иное число аргументов, чем было объявлено;
▸ имеет отличительный синтаксис объявления;
Нечто непохожее на метод
BLOCKS
{ }
DO END
: более высокий приоритет
: более низкий приоритет
Синтаксически блоки описываются при помощи ключевых символов:
BLOCKS
YIELD
BLOCK_GIVEN?
: вызов блока внутри метода
: проверка на наличие передаваемого блока в методе
Прочие особенности синтаксиса блоков:
{ |PARAM| … } : синтаксис описания принимаемых блоком параметров
BLOCKS
Блоки передаются всегда последним параметром. В большинстве случаев эта передача происходит сразу по факту описания, но так же блок можно передать как процедурный объект (об этом позже).
BLOCKS
ITERATORS
ITERATORS
ITERATOR
ITERATORS
EACH, MAP, SELECT, FIND, TIMES…
Так вот, многие из итераторов вам уже должны быть знакомы:
Все они работают с блоками.
ITERATORS
ITERATORS
Напишем собственный итератор:
PROCS
PROCS
PROC
PROCS
В чем смысл такого представления? В том, что теперь блок кода не подвязан к вызову метода yield и не обременен соответствующими ограничениями.
PROCS
PROCS
Как мы видим, одно из ключевых отличий блока от прока в том, что последний легко передавать как параметр.На самом деле, конкретный код модифицировать, чтобы передача блока как параметра все же состоялась.
PROCS
PROCS
Впрочем, это все равно не отменяет концептуальных ограничений блока.
С методом может быть связан только один блок и его нельзя присвоить переменной.
PROCS
Зато все виды процедурных объектов могут вызываться неявно.
Для этого достаточно указать в описании метода, который будет вызывать proс, псевдоаргумент, начинающийся с &.
PROCS
PROCS
Любой объект, реализующий метод to_proc и возвращающий процедурный объект, может быть передан методу как псевдоаргумент.
PROCS
PROCS
Существует синтаксический сахар, который позволяет передавать вместо блока просто символ.
Таким образом будет определен блок, в котором к аргументу блока будет вызываться одноименный с символом метод.
PROCS
LAMBDAS
LAMBDAS
LAMBDA
LAMBDAS
Proc
▸ return прерывает выполнение метода, в котором описан proc;
▸ не требует строгого соответствия аргументов;
▸ return прерывает выполнение самой lambda, возвращаясь в метод, в котором была описана lambda;
▸ требует строгого соответствия аргументов;
Lambda
LAMBDAS
Их синтаксис, как и представление, тоже отличаются:
LAMBDAS
У lambda есть еще один дополнительный вариант записи:
Ruby style guide рекомендует такой вид записи для однострочных лямбд.
BLOCKS, PROCS AND LAMBDAS
REFERENCES
▸ http://nashbridges.me/blocks-in-ruby
▸ http://nashbridges.me/procs-and-lambdas
▸ http://www.skorks.com/2013/04/ruby-ampersand-parameter-demystified/
▸ http://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/
THANK YOU!
Alex Mikitenko [email protected] https://github.com/nonkor
TO BE CONTINUED…