Когда вы передаете блок с &, вы конвертируете его в процесс. Важным моментом является то, что proc и лямбда отличаются (лямбда на самом деле является подклассом proc), особенно в том, как они справляются с возвратом.
Таким образом, ваш рефакторинг кода на самом деле эквивалентен:
p = Proc.new { return 10;}
def lab(block)
puts 'before'
puts block.call
puts 'after'
end
lab p
, который также генерирует LocalJumpError.
И вот почему: возврат proc возвращается из лексической области видимости, а лямбда-код возвращается в область выполнения. Таким образом, в то время как лямбда возвращается к lab
, переданный в нее proc возвращается во внешнюю область, в которой он был объявлен. Локальная ошибка перехода означает, что ей некуда деваться, потому что нет функции включения.
Язык программирования Ruby лучше всего говорит:
Procs имеет блочное поведение, а лямбды - как метод
Вы просто должны отслеживать, что вы используете, где. Как и предполагали другие, все, что вам нужно сделать, это сбросить return
с вашего блока, и все будет работать как положено.