Bagaimana saya kembali lebih awal dari tugas menyapu?

226

Saya memiliki tugas menyapu di mana saya melakukan beberapa pemeriksaan di awal, jika salah satu dari cek gagal saya ingin kembali lebih awal dari tugas menyapu, saya tidak ingin menjalankan salah satu kode yang tersisa.

Saya pikir solusinya adalah menempatkan pengembalian di mana saya ingin kembali dari kode tetapi saya mendapatkan kesalahan berikut

unexpected return
Janak
sumber

Jawaban:

285

Tugas Rake pada dasarnya adalah sebuah blok. Sebuah blok, kecuali lambdas, tidak mendukung return tetapi Anda dapat melewatkan pernyataan berikutnya menggunakan nextyang dalam tugas menyapu memiliki efek yang sama menggunakan return dalam suatu metode.

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

Atau Anda dapat memindahkan kode dalam suatu metode dan menggunakan pengembalian dalam metode tersebut.

task :foo do
  do_something
end

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

Saya lebih suka pilihan kedua.

Simone Carletti
sumber
18
Saya suka yang kedua juga. Semakin saya menggunakan rake, semakin saya suka menyimpan kode non-sepele di luar definisi tugas. Bukan aturan tegas 100%, tetapi tampaknya menjadi pedoman yang baik untuk bekerja.
Mike Woodhouse
6
Saya sudah mencoba breakdan saya mendapat kesalahan ini: rake dibatalkan! break from proc-closure (Lihat jejak lengkap dengan menjalankan tugas dengan --trace)
pupeno
4
Saya lebih suka menggunakan berikutnya. Mengapa kita harus mendeklarasikan metode baru hanya untuk mendukung pengembalian awal?
Derek Greer
5
Apa yang Anda lakukan jika Anda sangat bersarang dalam beberapa blok? ( nexthanya berfungsi jika ada "level" blok untuk keluar.
mjs
3
Peringatan: mendeklarasikan metode dalam tugas Rake adalah ide yang buruk karena mereka bersifat global untuk semua tugas Rake yang dimuat, tidak relevan dengan namespace. Selanjutnya digunakan alih-alih istirahat karena kode dalam blok dapat dipanggil beberapa kali oleh apa pun yang mengeksekusi blok (pikirkan metode .each).
Leslie Viljoen
181

Anda dapat menggunakan abort(message)dari dalam tugas untuk membatalkan tugas itu dengan pesan.

Sergikon
sumber
5
@ TylerRick Tidak, ini Kernel # batalkan .
Jo Liss
10
Cara ini lebih unggul untuk keluar dalam situasi yang tidak berhasil karena secara otomatis menetapkan status keluar.
samuil
Ini adalah pemenang. Juga cara mudah untuk memberikan umpan balik penggunaan untuk kesalahan argumen.
David Hempy
Sebaris dan jauh lebih jelas daripada next. Suka.
SomeSchmo
22

Saya cenderung menggunakan abortmana yang merupakan alternatif yang lebih baik dalam situasi seperti itu, misalnya:

task :foo do
  something = false
  abort 'Failed to proceed' unless something
end
khelll
sumber
1
Tetapi bagaimana Anda aborttanpa keluar dengan 1kode keluar? Tugas Rake sering digunakan di baris perintah untuk menentukan keberhasilan atau kegagalan. Apakah ada yang "sukses" abort?
Joshua Pinter
2
Menjawab pertanyaan saya sendiri: sepertinya exitadalah cara yang baik untuk keluar dengan sukses.
Joshua Pinter
19

Kembali dengan Kesalahan ❌

Jika Anda kembali dengan kesalahan (yaitu kode keluar 1) Anda ingin menggunakannya abort, yang juga mengambil param string opsional yang akan dikeluarkan saat keluar:

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

Di baris perintah:

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

Kembali dengan Sukses ✅

Jika Anda kembali tanpa kesalahan (yaitu kode keluar 0) Anda ingin menggunakannya exit, yang tidak menggunakan param string.

task :check do

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

end

Di baris perintah:

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

Ini penting jika Anda menggunakan ini dalam pekerjaan cron atau sesuatu yang perlu dilakukan setelahnya berdasarkan apakah tugas menyapu berhasil atau tidak.

Joshua Pinter
sumber
8

Jika Anda bermaksud keluar dari tugas menyapu tanpa menyebabkan "menyapu dibatalkan!" pesan yang akan dicetak, maka Anda dapat menggunakan "batalkan" atau "keluar". Tapi "batalkan", ketika digunakan dalam blok penyelamat, mengakhiri tugas serta mencetak seluruh kesalahan (bahkan tanpa menggunakan --trace). Jadi "keluar" adalah apa yang saya gunakan.

ZX12R
sumber
3
Secara umum, saya pikir menggunakan "keluar" bukannya pengembalian / istirahat adalah ide yang buruk karena tidak hanya melompat keluar dari arus proc / metode / etc. - ia keluar dari seluruh proses dan melewatkan kode apa pun yang mungkin dimaksudkan oleh metode pemanggil untuk dijalankan setelah itu (termasuk kemungkinan pembersihan). Tapi untuk tugas menyapu saya kira itu mungkin tidak masalah ...
Tyler Rick
0

Saya menggunakan nextpendekatan yang disarankan oleh Simone Carletti, karena ketika menguji tugas menyapu abort, yang sebenarnya hanya pembungkus exit, bukan perilaku yang diinginkan.

Contoh:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
Artur Beljajev
sumber