Как я могу вернуть что-то досрочно из блока?

Если бы я хотел сделать что-то вроде этого:

collection.each do |i|
   return nil if i == 3

   ..many lines of code here..
end

Как мне добиться такого эффекта? Я знаю, что могу просто обернуть все внутри блока большим оператором if, но я бы хотел избежать вложенности, если это возможно.

Break здесь не сработает, потому что я не хочу останавливать итерацию остальных элементов.


person ryeguy    schedule 25.03.2010    source источник


Ответы (2)


next внутри блока возвращается из блока. break внутри блока возвращается из функции, которая уступила место блоку. Для each это означает, что break выходит из цикла, а next переходит к следующей итерации цикла (отсюда и имена). Вы можете возвращать значения с помощью next value и break value.

person sepp2k    schedule 25.03.2010
comment
break value у меня не работал, а next value работал нормально. Большое спасибо. - person Francesco Belladonna; 21.09.2013
comment
Я не уверен, что ваше определение следующего и перерыва правильное. По крайней мере, они сбивают с толку. break выходит из самого внутреннего цикла, затем перемещает вас к следующей итерации. источник: tutorialspoint.com/ruby/ruby_loops.htm - person WattsInABox; 19.12.2013
comment
@WattsInABox next и break никоим образом не относятся к циклическим конструкциям, поэтому статья, на которую вы ссылаетесь, вводит в заблуждение (поскольку она явно подразумевает обратное). И мои описания определенно верны, когда next и break используются внутри блоков (обратите внимание, что while и for редко, если вообще когда-либо, используются в Ruby, поэтому 99% использования next и break находятся внутри блоков). - person sepp2k; 20.12.2013
comment
Я думаю, вы имеете в виду блоки без цикла. Вот что сбивает с толку. Кроме того, я не согласен с вашим утверждением на 99%, но это другой аргумент. - person WattsInABox; 20.12.2013
comment
Я искал для класса Array особый метод, потому что привык к таким приятным вещам, как .detect, .map, .reduce. Я знал, что упускаю что-то очевидное, когда не мог найти ничего подобного. Спасибо. - person xander-miller; 26.02.2017

В этом случае вы можете использовать break для преждевременного завершения цикла:

collection.each do |i|
  break if i == 3
  ...many lines
end

... конечно, это предполагает, что вы на самом деле не хотите возвращать значение, просто вырвитесь из блока.

person Sniggerfardimungus    schedule 25.03.2010
comment
Это не просто вернется из блока, оно вернется из каждого. Таким образом, цикл закончится, а не продолжится со следующим значением. Не уверен, что это то, что задумано. - person sepp2k; 25.03.2010
comment
Вы можете использовать значение с break в Ruby - break 5 приведет к тому, что each вернет 5. - person Chuck; 25.03.2010
comment
Спасибо, но я не хочу останавливать итерацию. - person ryeguy; 25.03.2010