Як повернутися рано з грабля?


226

У мене є завдання грабля, де я виконую кілька перевірок на початку, якщо одна з перевірок не вдалася, я хотів би повернутися до початку граблі, я не хочу виконувати жоден із решти коду.

Я думав, що рішенням було б повернути туди, де я хотів повернутися з коду, але я отримую таку помилку

unexpected return

Відповіді:


285

Завдання Rake - це в основному блок. Блок, за винятком лямбда, не підтримує return, але ви можете перейти до наступного оператора, використовуючи nextякий у задачі на рейк має той самий ефект, як використання return у методі.

task :foo do
  puts "printed"
  next
  puts "never printed"
end

Або ви можете перемістити код у методі та використовувати return у методі.

task :foo do
  do_something
end

def do_something
  puts "startd"
  return
  puts "end"
end

Я віддаю перевагу другому вибору.


18
Другий мені теж подобається. Чим більше я використовую рейк, тим більше мені подобається тримати нетривіальний код поза визначенням завдання. Не є 100% твердим правилом, але, здається, є гарним орієнтиром для роботи.
Майк Вудхаус

6
Я спробував, breakі у мене є ця помилка: граблі перервано! перерва від закриття закриття (Дивіться повний слід, виконуючи завдання з - слідом)
pupeno

4
Я вважаю за краще використовувати наступний. Чому ми повинні оголосити новий метод просто для підтримки раннього повернення?
Дерек Грір

5
Що робити, якщо ти глибоко вкладений у кілька блоків? ( nextПрацює тільки якщо є на «рівні» блоку вирватися з.
MJS

3
Попередження: оголошення методів у задачах Rake є поганою ідеєю, оскільки вони глобальні для всіх завантажених завдань Rake, не мають значення для простору імен. Далі використовується замість перерви, оскільки код у блоці може викликатися кілька разів будь-яким виконанням блоку (придумайте метод .each).
Леслі Вільйон

181

Ви можете використовувати abort(message)всередині завдання, щоб перервати це завдання з повідомленням.


5
@TylerRick Ні, це Kernel # аборт .
Джо Лісс

10
Цей спосіб є кращим для виходу з невдалої ситуації, оскільки він автоматично встановлює статус виходу.
самуїл

Це переможець. Також простий спосіб надати відгук про використання для помилок аргументів.
Девід Хемпі

Вбудований і набагато більше пояснювальний, ніж next. Любіть це.
SomeSchmo

22

Я схильний використовувати, abortщо є кращою альтернативою в таких ситуаціях, наприклад:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end

1
Але як вам abortне вийти з 1кодом виходу? Завдання граблів часто використовуються в командному рядку для визначення успіху чи невдачі. Чи є "успішний" abort?
Джошуа Пінтер

2
Відповів на власні запитання: схоже exit, це хороший спосіб успішного виходу.
Джошуа Пінтер

19

Повернення з помилкою ❌

Якщо ви повертаєтесь з помилкою (тобто кодом виходу 1), вам потрібно скористатися abort, що також приймає необов'язковий параметр рядка, який буде виведений при виході:

task :check do

  # If any of your checks fail, you can exit early like this.
  abort( "One of the checks has failed!" ) if check_failed?

end

У командному рядку:

$ rake check && echo "All good"
#=> One of the checks has failed!

Повернення з успіхом ✅

Якщо ви повертаєтесь без помилки (тобто код виходу 0), вам потрібно скористатися exit, що не приймає параметр рядка.

task :check do

  # If any of your checks fail, you can exit early like this.
  exit if check_failed?

end

У командному рядку:

$ rake check && echo "All good"
#=> All good

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



8

Якщо ви мали на увазі вихід із граблі, не викликаючи "граблі перервано!" повідомлення для друку, тоді ви можете використовувати або "перервати", або "вихід". Але "перервати", коли використовується в рятувальному блоці, припиняє завдання, а також виводить всю помилку (навіть без використання - сліду). Тож "вихід" - це те, що я використовую.


3
Взагалі, я думаю, що використовувати "вихід" замість повернення / перерви - це погана ідея, оскільки вона не просто вискочить із поточного методу proc / method / тощо. - він закриває весь процес і пропускає будь-який код, який, можливо, мав на меті запустити зателефонований метод (включаючи, можливо, деяку очистку). Але для завдання граблі, я думаю, це, мабуть, не проблема ...
Тайлер Рік

0

Я використовував nextпідхід, запропонований Симоне Карлетті, оскільки під час тестування граблі abort, яка насправді є лише обгорткоюexit , не є бажаною поведінкою.

Приклад:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.