Як я можу повернути щось достроково з блоку?


90

Якби я хотів зробити щось подібне:

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

   ..many lines of code here..
end

Як би я отримав такий ефект? Я знаю, що міг би просто обернути все усередині блоку великим оператором if, але я хотів би уникнути вкладеності, якщо це можливо.

Перерва тут не спрацює, оскільки я не хочу зупиняти ітерацію решти елементів.

Відповіді:


176

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


53
+1 для next valueі break value. Саме те, що я шукав.
Джошуа Пінтер,

1
break valueне працював у мене, хоча next valueпрацював нормально. Дуже дякую.
Франческо Беладонна

4
Я не впевнений, що ваше визначення наступного та перерви правильне. Принаймні, вони заплутані. break виходить із внутрішнього циклу, наступний рухає вас до наступної ітерації. джерело: tutorialspoint.com/ruby/ruby_loops.htm
WattsInABox

3
@WattsInABox nextі breakжодним чином не властиві циклічним конструкціям, тому стаття, на яку ви посилаєтесь, дуже вводить в оману (оскільки вона в значній мірі передбачає протилежне). І мої описи, безумовно, є правильними, коли nextі breakвикористовуються всередині блоків (зауважте, що whileі forрідко, якщо взагалі колись, використовуються в Ruby, тож 99% випадків використання nextі breakзнаходяться всередині блоків).
sepp2k

Я думаю, ви маєте на увазі непетельні блоки. Ось що в ньому бентежить. Крім того, я не погоджуюсь із вашим твердженням на 99%, але це вже інший аргумент.
WattsInABox

11
#!/usr/bin/ruby

collection = [1, 2, 3, 4, 5 ]

stopped_at = collection.each do |i|
   break i if i == 3

   puts "Processed #{i}"
end

puts "Stopped at and did not process #{stopped_at}"

5

У цьому випадку ви можете використовувати break, щоб достроково завершити цикл:

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

... звичайно, це припускає, що ви насправді не прагнете повернути значення, просто вирвіться з блоку.


Це не просто повернеться з блоку, воно повернеться з кожного. Отже, цикл закінчується, а не продовжується з наступним значенням. Не впевнений, що саме це призначено.
sepp2k

4
Ви можете використовувати значення breakв Ruby - break 5призведе eachдо повернення 5.
Чак

1
Дякую, але я не хочу зупиняти ітерацію.
ryeguy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.