Làm thế nào để tôi trở về sớm từ một nhiệm vụ cào?


226

Tôi có một nhiệm vụ cào khi tôi thực hiện một số kiểm tra lúc đầu, nếu một trong các kiểm tra không thành công tôi muốn quay lại sớm từ nhiệm vụ cào, tôi không muốn thực hiện bất kỳ mã nào còn lại.

Tôi nghĩ giải pháp sẽ là trả lại nơi tôi muốn trả về từ mã nhưng tôi gặp lỗi sau

unexpected return

Câu trả lời:


285

Một nhiệm vụ Rake về cơ bản là một khối. Một khối, ngoại trừ lambdas, không hỗ trợ trả về nhưng bạn có thể bỏ qua câu lệnh tiếp theo bằng cách sử dụng hàm nexttrong một tác vụ cào có tác dụng tương tự như sử dụng return trong một phương thức.

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

Hoặc bạn có thể di chuyển mã trong một phương thức và sử dụng return trong phương thức.

task :foo do
  do_something
end

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

Tôi thích sự lựa chọn thứ hai.


18
Tôi cũng thích cái thứ hai nhất. Tôi càng sử dụng rake, tôi càng muốn giữ mã không tầm thường bên ngoài định nghĩa tác vụ. Không phải là một quy tắc vững chắc 100%, nhưng dường như là một hướng dẫn tốt để làm việc.
Mike Woodhouse

6
Tôi đã thử với breakvà tôi đã gặp lỗi này: cào bỏ! nghỉ từ đóng cửa (Xem toàn bộ dấu vết bằng cách chạy tác vụ với --trace)
Pupeno

4
Tôi thích sử dụng tiếp theo. Tại sao chúng ta nên khai báo một phương thức mới chỉ để hỗ trợ trả về sớm?
Derek Greer

5
Bạn sẽ làm gì nếu bạn được lồng sâu trong nhiều khối? ( nextchỉ hoạt động nếu có "cấp độ" của khối thoát ra.
mjs

3
Cảnh báo: khai báo các phương thức trong các tác vụ Rake là một ý tưởng tồi vì chúng là toàn cầu đối với tất cả các tác vụ Rake được tải, không liên quan đến không gian tên. Tiếp theo được sử dụng thay vì ngắt vì mã trong khối có thể được gọi nhiều lần bởi bất cứ điều gì đang thực thi khối (nghĩ về phương thức .each).
Leslie Viljoen

181

Bạn có thể sử dụng abort(message)từ bên trong tác vụ để hủy bỏ tác vụ đó bằng một tin nhắn.


5
@TylerRick Không, đó là Kernel # abort .
Jo Liss

10
Cách này tốt hơn khi thoát trong các tình huống không thành công vì nó tự động đặt trạng thái thoát.
samuil

Đây là một người chiến thắng. Cũng là một cách dễ dàng để cung cấp phản hồi sử dụng cho các lỗi đối số.
David Hempy

Nội tuyến và nhiều giải thích hơn next. Yêu nó.
Một số

22

Tôi có xu hướng sử dụng abortđó là một thay thế tốt hơn trong các tình huống như vậy, ví dụ:

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

1
Nhưng làm thế nào để bạn abortkhông thoát ra với một 1mã thoát? Các tác vụ cào thường được sử dụng trong dòng lệnh để xác định thành công hay thất bại. Có "thành công" abortkhông?
Joshua Pinter

2
Trả lời câu hỏi của riêng tôi: có vẻ như exitlà một cách tốt để thoát thành công.
Joshua Pinter

19

Quay trở lại với một lỗi

Nếu bạn quay lại với một lỗi (tức là mã thoát 1), bạn sẽ muốn sử dụng abort, điều này cũng sẽ có một tham số chuỗi tùy chọn sẽ được đưa ra khi thoát:

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

Trên dòng lệnh:

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

Trở lại với thành công

Nếu bạn quay lại mà không gặp lỗi (tức là mã thoát 0), bạn sẽ muốn sử dụng exit, điều này không lấy tham số chuỗi.

task :check do

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

end

Trên dòng lệnh:

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

Điều này rất quan trọng nếu bạn đang sử dụng công việc này trong một công việc định kỳ hoặc một việc gì đó cần phải làm gì đó sau đó dựa trên việc nhiệm vụ cào có thành công hay không.



8

Nếu bạn có nghĩa là thoát khỏi một nhiệm vụ cào mà không làm cho "cào bị hủy bỏ!" tin nhắn sẽ được in, sau đó bạn có thể sử dụng "hủy bỏ" hoặc "thoát". Nhưng "hủy bỏ", khi được sử dụng trong khối cứu hộ, chấm dứt tác vụ cũng như in toàn bộ lỗi (ngay cả khi không sử dụng --trace). Vì vậy, "thoát" là những gì tôi sử dụng.


3
Nói chung, tôi nghĩ rằng sử dụng "exit" thay vì lợi nhuận / break là một ý tưởng tồi vì nó không chỉ là nhảy ra khỏi hiện proc / phương pháp / etc. - nó thoát khỏi toàn bộ quá trình và bỏ qua bất kỳ mã nào mà phương thức người gọi có thể dự định sẽ được chạy sau đó (bao gồm cả khả năng dọn dẹp). Nhưng đối với một nhiệm vụ cào, tôi đoán có lẽ đó không phải là vấn đề ...
Tyler Rick

0

Tôi đã sử dụng nextphương pháp được đề xuất bởi Simone Carletti, vì khi thử nghiệm tác vụ cào abort, mà trên thực tế chỉ là một trình bao bọc exit, không phải là hành vi mong muốn.

Thí dụ:

task auto_invoice: :environment do
  if Application.feature_disabled?(:auto_invoice)
    $stderr.puts 'Feature is disabled, aborting.'
  next
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.